Merge
authordsamersoff
Sun, 30 Mar 2014 03:29:48 -0700
changeset 23519 9a78876cefeb
parent 23511 a6e433ebd892 (current diff)
parent 23518 00028482ef09 (diff)
child 23520 86ab5bae08bd
Merge
hotspot/src/share/vm/oops/method.cpp
hotspot/src/share/vm/runtime/arguments.cpp
--- a/hotspot/src/share/vm/memory/filemap.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/memory/filemap.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,8 +32,8 @@
 //  header: dump of archive instance plus versioning info, datestamp, etc.
 //   [magic # = 0xF00BABA2]
 //  ... padding to align on page-boundary
-//  read-write space from CompactingPermGenGen
-//  read-only space from CompactingPermGenGen
+//  read-write space
+//  read-only space
 //  misc data (block offset table, string table, symbols, dictionary, etc.)
 //  tag(666)
 
--- a/hotspot/src/share/vm/oops/constMethod.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/constMethod.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,68 +27,61 @@
 
 #include "oops/oop.hpp"
 
-// An ConstMethod* represents portions of a Java method which
-// do not vary.
+// An ConstMethod represents portions of a Java method which are not written to after
+// the classfile is parsed(*see below).  This part of the method can be shared across
+// processes in a read-only section with Class Data Sharing (CDS).  It's important
+// that this class doesn't have virtual functions because the vptr cannot be shared
+// with CDS.
+//   (*)RewriteByteCodes and RewriteFrequentPairs is an exception but turned off in CDS
 //
-// Memory layout (each line represents a word). Note that most
-// applications load thousands of methods, so keeping the size of this
+// Note that most applications load thousands of methods, so keeping the size of this
 // structure small has a big impact on footprint.
+
+// The actual bytecodes are inlined after the end of the ConstMethod struct.
+//
+// The line number table is compressed and inlined following the byte codes. It is
+// found as the first byte following the byte codes.  Note that accessing the line
+// number and local variable tables is not performance critical at all.
+//
+// The checked exceptions table and the local variable table are inlined after the
+// line number table, and indexed from the end of the method. We do not compress the
+// checked exceptions table since the average length is less than 2, and it is used
+// by reflection so access should be fast.  We do not bother to compress the local
+// variable table either since it is mostly absent.
+//
 //
-// |------------------------------------------------------|
-// | header                                               |
-// | klass                                                |
-// |------------------------------------------------------|
-// | fingerprint 1                                        |
-// | fingerprint 2                                        |
-// | constants                      (oop)                 |
-// | stackmap_data                  (oop)                 |
-// | constMethod_size                                     |
-// | interp_kind  | flags    | code_size                  |
-// | name index              | signature index            |
-// | method_idnum            | max_stack                  |
-// | max_locals              | size_of_parameters         |
-// |------------------------------------------------------|
-// |                                                      |
-// | byte codes                                           |
-// |                                                      |
-// |------------------------------------------------------|
-// | compressed linenumber table                          |
-// |  (see class CompressedLineNumberReadStream)          |
-// |  (note that length is unknown until decompressed)    |
-// |  (access flags bit tells whether table is present)   |
-// |  (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*)                  |
-// |------------------------------------------------------|
-// | 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*)                  |
-// |------------------------------------------------------|
-// | 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*)                  |
-// |------------------------------------------------------|
-// | method parameters elements + length (length last)    |
-// |  (length is u2, elements are u2, u4 structures)      |
-// |  (see class MethodParametersElement)                 |
-// |  (access flags bit tells whether table is present)   |
-// |  (indexed from end of ConstMethod*)                  |
-// |------------------------------------------------------|
-// | generic signature index (u2)                         |
-// |  (indexed from start of constMethodOop)              |
-// |------------------------------------------------------|
-// | annotations arrays - method, parameter, type, default|
-// | pointer to Array<u1> if annotation is present        |
-// |------------------------------------------------------|
+//  ConstMethod embedded field layout (after declared fields):
+//    [EMBEDDED byte codes]
+//    [EMBEDDED compressed linenumber table]
+//     (see class CompressedLineNumberReadStream)
+//     (note that length is unknown until decompressed)
+//     (access flags bit tells whether table is present)
+//     (indexed from start of ConstMethod)
+//     (elements not necessarily sorted!)
+//    [EMBEDDED 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*)
+//    [EMBEDDED 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*)
+//    [EMBEDDED 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*)
+//    [EMBEDDED method parameters elements + length (length last)]
+//     (length is u2, elements are u2, u4 structures)
+//     (see class MethodParametersElement)
+//     (access flags bit tells whether table is present)
+//     (indexed from end of ConstMethod*)
+//    [EMBEDDED generic signature index (u2)]
+//     (indexed from end of constMethodOop)
+//    [EMBEDDED annotations arrays - method, parameter, type, default]
+//      pointer to Array<u1> if annotation is present
 //
 // IMPORTANT: If anything gets added here, there need to be changes to
 // ensure that ServicabilityAgent doesn't get broken as a result!
--- a/hotspot/src/share/vm/oops/constantPool.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -180,12 +180,12 @@
   return (i < 0) ? _no_index_sentinel : i;
 }
 
-Klass* ConstantPool::klass_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
+Klass* ConstantPool::klass_at_impl(constantPoolHandle this_cp, int which, TRAPS) {
   // A resolved constantPool entry will contain a Klass*, otherwise a Symbol*.
   // It is not safe to rely on the tag bit's here, since we don't have a lock, and the entry and
   // tag is not updated atomicly.
 
-  CPSlot entry = this_oop->slot_at(which);
+  CPSlot entry = this_cp->slot_at(which);
   if (entry.is_resolved()) {
     assert(entry.get_klass()->is_klass(), "must be");
     // Already resolved - return entry.
@@ -204,15 +204,15 @@
 
   Symbol* name = NULL;
   Handle       loader;
-  {  MonitorLockerEx ml(this_oop->lock());
+  {  MonitorLockerEx ml(this_cp->lock());
 
-    if (this_oop->tag_at(which).is_unresolved_klass()) {
-      if (this_oop->tag_at(which).is_unresolved_klass_in_error()) {
+    if (this_cp->tag_at(which).is_unresolved_klass()) {
+      if (this_cp->tag_at(which).is_unresolved_klass_in_error()) {
         in_error = true;
       } else {
         do_resolve = true;
-        name   = this_oop->unresolved_klass_at(which);
-        loader = Handle(THREAD, this_oop->pool_holder()->class_loader());
+        name   = this_cp->unresolved_klass_at(which);
+        loader = Handle(THREAD, this_cp->pool_holder()->class_loader());
       }
     }
   } // unlocking constantPool
@@ -221,26 +221,26 @@
   // The original attempt to resolve this constant pool entry failed so find the
   // original error and throw it again (JVMS 5.4.3).
   if (in_error) {
-    Symbol* error = SystemDictionary::find_resolution_error(this_oop, which);
+    Symbol* error = SystemDictionary::find_resolution_error(this_cp, which);
     guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table");
     ResourceMark rm;
     // exception text will be the class name
-    const char* className = this_oop->unresolved_klass_at(which)->as_C_string();
+    const char* className = this_cp->unresolved_klass_at(which)->as_C_string();
     THROW_MSG_0(error, className);
   }
 
   if (do_resolve) {
-    // this_oop must be unlocked during resolve_or_fail
-    oop protection_domain = this_oop->pool_holder()->protection_domain();
+    // this_cp must be unlocked during resolve_or_fail
+    oop protection_domain = this_cp->pool_holder()->protection_domain();
     Handle h_prot (THREAD, protection_domain);
-    Klass* k_oop = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);
+    Klass* kk = SystemDictionary::resolve_or_fail(name, loader, h_prot, true, THREAD);
     KlassHandle k;
     if (!HAS_PENDING_EXCEPTION) {
-      k = KlassHandle(THREAD, k_oop);
+      k = KlassHandle(THREAD, kk);
       // preserve the resolved klass.
-      mirror_handle = Handle(THREAD, k_oop->java_mirror());
+      mirror_handle = Handle(THREAD, kk->java_mirror());
       // Do access check for klasses
-      verify_constant_pool_resolve(this_oop, k, THREAD);
+      verify_constant_pool_resolve(this_cp, k, THREAD);
     }
 
     // Failed to resolve class. We must record the errors so that subsequent attempts
@@ -251,12 +251,12 @@
 
       bool throw_orig_error = false;
       {
-        MonitorLockerEx ml(this_oop->lock());
+        MonitorLockerEx ml(this_cp->lock());
 
         // some other thread has beaten us and has resolved the class.
-        if (this_oop->tag_at(which).is_klass()) {
+        if (this_cp->tag_at(which).is_klass()) {
           CLEAR_PENDING_EXCEPTION;
-          entry = this_oop->resolved_klass_at(which);
+          entry = this_cp->resolved_klass_at(which);
           return entry.get_klass();
         }
 
@@ -267,12 +267,12 @@
           // and OutOfMemoryError, etc, or if the thread was hit by stop()
           // Needs clarification to section 5.4.3 of the VM spec (see 6308271)
         }
-        else if (!this_oop->tag_at(which).is_unresolved_klass_in_error()) {
-          SystemDictionary::add_resolution_error(this_oop, which, error);
-          this_oop->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError);
+        else if (!this_cp->tag_at(which).is_unresolved_klass_in_error()) {
+          SystemDictionary::add_resolution_error(this_cp, which, error);
+          this_cp->tag_at_put(which, JVM_CONSTANT_UnresolvedClassInError);
         } else {
           // some other thread has put the class in error state.
-          error = SystemDictionary::find_resolution_error(this_oop, which);
+          error = SystemDictionary::find_resolution_error(this_cp, which);
           assert(error != NULL, "checking");
           throw_orig_error = true;
         }
@@ -281,7 +281,7 @@
       if (throw_orig_error) {
         CLEAR_PENDING_EXCEPTION;
         ResourceMark rm;
-        const char* className = this_oop->unresolved_klass_at(which)->as_C_string();
+        const char* className = this_cp->unresolved_klass_at(which)->as_C_string();
         THROW_MSG_0(error, className);
       }
 
@@ -305,32 +305,32 @@
           }
         }
       }
-      if (k() != this_oop->pool_holder()) {
+      if (k() != this_cp->pool_holder()) {
         // only print something if the classes are different
         if (source_file != NULL) {
           tty->print("RESOLVE %s %s %s:%d\n",
-                     this_oop->pool_holder()->external_name(),
+                     this_cp->pool_holder()->external_name(),
                      InstanceKlass::cast(k())->external_name(), source_file, line_number);
         } else {
           tty->print("RESOLVE %s %s\n",
-                     this_oop->pool_holder()->external_name(),
+                     this_cp->pool_holder()->external_name(),
                      InstanceKlass::cast(k())->external_name());
         }
       }
       return k();
     } else {
-      MonitorLockerEx ml(this_oop->lock());
+      MonitorLockerEx ml(this_cp->lock());
       // Only updated constant pool - if it is resolved.
-      do_resolve = this_oop->tag_at(which).is_unresolved_klass();
+      do_resolve = this_cp->tag_at(which).is_unresolved_klass();
       if (do_resolve) {
-        ClassLoaderData* this_key = this_oop->pool_holder()->class_loader_data();
+        ClassLoaderData* this_key = this_cp->pool_holder()->class_loader_data();
         this_key->record_dependency(k(), CHECK_NULL); // Can throw OOM
-        this_oop->klass_at_put(which, k());
+        this_cp->klass_at_put(which, k());
       }
     }
   }
 
-  entry = this_oop->resolved_klass_at(which);
+  entry = this_cp->resolved_klass_at(which);
   assert(entry.is_resolved() && entry.get_klass()->is_klass(), "must be resolved at this point");
   return entry.get_klass();
 }
@@ -340,8 +340,8 @@
 // by compiler and exception handling.  Also used to avoid classloads for
 // instanceof operations. Returns NULL if the class has not been loaded or
 // if the verification of constant pool failed
-Klass* ConstantPool::klass_at_if_loaded(constantPoolHandle this_oop, int which) {
-  CPSlot entry = this_oop->slot_at(which);
+Klass* ConstantPool::klass_at_if_loaded(constantPoolHandle this_cp, int which) {
+  CPSlot entry = this_cp->slot_at(which);
   if (entry.is_resolved()) {
     assert(entry.get_klass()->is_klass(), "must be");
     return entry.get_klass();
@@ -349,8 +349,8 @@
     assert(entry.is_unresolved(), "must be either symbol or klass");
     Thread *thread = Thread::current();
     Symbol* name = entry.get_symbol();
-    oop loader = this_oop->pool_holder()->class_loader();
-    oop protection_domain = this_oop->pool_holder()->protection_domain();
+    oop loader = this_cp->pool_holder()->class_loader();
+    oop protection_domain = this_cp->pool_holder()->protection_domain();
     Handle h_prot (thread, protection_domain);
     Handle h_loader (thread, loader);
     Klass* k = SystemDictionary::find(name, h_loader, h_prot, thread);
@@ -360,7 +360,7 @@
       EXCEPTION_MARK;
       KlassHandle klass(THREAD, k);
       // return NULL if verification fails
-      verify_constant_pool_resolve(this_oop, klass, THREAD);
+      verify_constant_pool_resolve(this_cp, klass, THREAD);
       if (HAS_PENDING_EXCEPTION) {
         CLEAR_PENDING_EXCEPTION;
         return NULL;
@@ -373,8 +373,8 @@
 }
 
 
-Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_oop, int which) {
-  return klass_at_if_loaded(this_oop, this_oop->klass_ref_index_at(which));
+Klass* ConstantPool::klass_ref_at_if_loaded(constantPoolHandle this_cp, int which) {
+  return klass_at_if_loaded(this_cp, this_cp->klass_ref_index_at(which));
 }
 
 
@@ -486,11 +486,11 @@
 }
 
 
-void ConstantPool::verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle k, TRAPS) {
+void ConstantPool::verify_constant_pool_resolve(constantPoolHandle this_cp, KlassHandle k, TRAPS) {
  if (k->oop_is_instance() || k->oop_is_objArray()) {
-    instanceKlassHandle holder (THREAD, this_oop->pool_holder());
-    Klass* elem_oop = k->oop_is_instance() ? k() : ObjArrayKlass::cast(k())->bottom_klass();
-    KlassHandle element (THREAD, elem_oop);
+    instanceKlassHandle holder (THREAD, this_cp->pool_holder());
+    Klass* elem = k->oop_is_instance() ? k() : ObjArrayKlass::cast(k())->bottom_klass();
+    KlassHandle element (THREAD, elem);
 
     // The element type could be a typeArray - we only need the access check if it is
     // an reference to another class
@@ -559,10 +559,10 @@
 }
 
 
-void ConstantPool::resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS) {
-  for (int index = 1; index < this_oop->length(); index++) { // Index 0 is unused
-    if (this_oop->tag_at(index).is_string()) {
-      this_oop->string_at(index, CHECK);
+void ConstantPool::resolve_string_constants_impl(constantPoolHandle this_cp, TRAPS) {
+  for (int index = 1; index < this_cp->length(); index++) { // Index 0 is unused
+    if (this_cp->tag_at(index).is_string()) {
+      this_cp->string_at(index, CHECK);
     }
   }
 }
@@ -585,11 +585,11 @@
 
 // If resolution for MethodHandle or MethodType fails, save the exception
 // in the resolution error table, so that the same exception is thrown again.
-void ConstantPool::save_and_throw_exception(constantPoolHandle this_oop, int which,
+void ConstantPool::save_and_throw_exception(constantPoolHandle this_cp, int which,
                                      int tag, TRAPS) {
   ResourceMark rm;
   Symbol* error = PENDING_EXCEPTION->klass()->name();
-  MonitorLockerEx ml(this_oop->lock());  // lock cpool to change tag.
+  MonitorLockerEx ml(this_cp->lock());  // lock cpool to change tag.
 
   int error_tag = (tag == JVM_CONSTANT_MethodHandle) ?
            JVM_CONSTANT_MethodHandleInError : JVM_CONSTANT_MethodTypeInError;
@@ -601,12 +601,12 @@
     // and OutOfMemoryError, etc, or if the thread was hit by stop()
     // Needs clarification to section 5.4.3 of the VM spec (see 6308271)
 
-  } else if (this_oop->tag_at(which).value() != error_tag) {
-    SystemDictionary::add_resolution_error(this_oop, which, error);
-    this_oop->tag_at_put(which, error_tag);
+  } else if (this_cp->tag_at(which).value() != error_tag) {
+    SystemDictionary::add_resolution_error(this_cp, which, error);
+    this_cp->tag_at_put(which, error_tag);
   } else {
     // some other thread has put the class in error state.
-    error = SystemDictionary::find_resolution_error(this_oop, which);
+    error = SystemDictionary::find_resolution_error(this_cp, which);
     assert(error != NULL, "checking");
     CLEAR_PENDING_EXCEPTION;
     THROW_MSG(error, "");
@@ -617,7 +617,7 @@
 // Called to resolve constants in the constant pool and return an oop.
 // Some constant pool entries cache their resolved oop. This is also
 // called to create oops from constants to use in arguments for invokedynamic
-oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS) {
+oop ConstantPool::resolve_constant_at_impl(constantPoolHandle this_cp, int index, int cache_index, TRAPS) {
   oop result_oop = NULL;
   Handle throw_exception;
 
@@ -625,23 +625,23 @@
     // It is possible that this constant is one which is cached in the objects.
     // We'll do a linear search.  This should be OK because this usage is rare.
     assert(index > 0, "valid index");
-    cache_index = this_oop->cp_to_object_index(index);
+    cache_index = this_cp->cp_to_object_index(index);
   }
   assert(cache_index == _no_index_sentinel || cache_index >= 0, "");
   assert(index == _no_index_sentinel || index >= 0, "");
 
   if (cache_index >= 0) {
-    result_oop = this_oop->resolved_references()->obj_at(cache_index);
+    result_oop = this_cp->resolved_references()->obj_at(cache_index);
     if (result_oop != NULL) {
       return result_oop;
       // That was easy...
     }
-    index = this_oop->object_to_cp_index(cache_index);
+    index = this_cp->object_to_cp_index(cache_index);
   }
 
   jvalue prim_value;  // temp used only in a few cases below
 
-  int tag_value = this_oop->tag_at(index).value();
+  int tag_value = this_cp->tag_at(index).value();
 
   switch (tag_value) {
 
@@ -650,7 +650,7 @@
   case JVM_CONSTANT_Class:
     {
       assert(cache_index == _no_index_sentinel, "should not have been set");
-      Klass* resolved = klass_at_impl(this_oop, index, CHECK_NULL);
+      Klass* resolved = klass_at_impl(this_cp, index, CHECK_NULL);
       // ldc wants the java mirror.
       result_oop = resolved->java_mirror();
       break;
@@ -658,17 +658,17 @@
 
   case JVM_CONSTANT_String:
     assert(cache_index != _no_index_sentinel, "should have been set");
-    if (this_oop->is_pseudo_string_at(index)) {
-      result_oop = this_oop->pseudo_string_at(index, cache_index);
+    if (this_cp->is_pseudo_string_at(index)) {
+      result_oop = this_cp->pseudo_string_at(index, cache_index);
       break;
     }
-    result_oop = string_at_impl(this_oop, index, cache_index, CHECK_NULL);
+    result_oop = string_at_impl(this_cp, index, cache_index, CHECK_NULL);
     break;
 
   case JVM_CONSTANT_MethodHandleInError:
   case JVM_CONSTANT_MethodTypeInError:
     {
-      Symbol* error = SystemDictionary::find_resolution_error(this_oop, index);
+      Symbol* error = SystemDictionary::find_resolution_error(this_cp, index);
       guarantee(error != (Symbol*)NULL, "tag mismatch with resolution error table");
       ResourceMark rm;
       THROW_MSG_0(error, "");
@@ -677,72 +677,72 @@
 
   case JVM_CONSTANT_MethodHandle:
     {
-      int ref_kind                 = this_oop->method_handle_ref_kind_at(index);
-      int callee_index             = this_oop->method_handle_klass_index_at(index);
-      Symbol*  name =      this_oop->method_handle_name_ref_at(index);
-      Symbol*  signature = this_oop->method_handle_signature_ref_at(index);
+      int ref_kind                 = this_cp->method_handle_ref_kind_at(index);
+      int callee_index             = this_cp->method_handle_klass_index_at(index);
+      Symbol*  name =      this_cp->method_handle_name_ref_at(index);
+      Symbol*  signature = this_cp->method_handle_signature_ref_at(index);
       if (PrintMiscellaneous)
         tty->print_cr("resolve JVM_CONSTANT_MethodHandle:%d [%d/%d/%d] %s.%s",
-                      ref_kind, index, this_oop->method_handle_index_at(index),
+                      ref_kind, index, this_cp->method_handle_index_at(index),
                       callee_index, name->as_C_string(), signature->as_C_string());
       KlassHandle callee;
-      { Klass* k = klass_at_impl(this_oop, callee_index, CHECK_NULL);
+      { Klass* k = klass_at_impl(this_cp, callee_index, CHECK_NULL);
         callee = KlassHandle(THREAD, k);
       }
-      KlassHandle klass(THREAD, this_oop->pool_holder());
+      KlassHandle klass(THREAD, this_cp->pool_holder());
       Handle value = SystemDictionary::link_method_handle_constant(klass, ref_kind,
                                                                    callee, name, signature,
                                                                    THREAD);
       result_oop = value();
       if (HAS_PENDING_EXCEPTION) {
-        save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL);
+        save_and_throw_exception(this_cp, index, tag_value, CHECK_NULL);
       }
       break;
     }
 
   case JVM_CONSTANT_MethodType:
     {
-      Symbol*  signature = this_oop->method_type_signature_at(index);
+      Symbol*  signature = this_cp->method_type_signature_at(index);
       if (PrintMiscellaneous)
         tty->print_cr("resolve JVM_CONSTANT_MethodType [%d/%d] %s",
-                      index, this_oop->method_type_index_at(index),
+                      index, this_cp->method_type_index_at(index),
                       signature->as_C_string());
-      KlassHandle klass(THREAD, this_oop->pool_holder());
+      KlassHandle klass(THREAD, this_cp->pool_holder());
       Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
       result_oop = value();
       if (HAS_PENDING_EXCEPTION) {
-        save_and_throw_exception(this_oop, index, tag_value, CHECK_NULL);
+        save_and_throw_exception(this_cp, index, tag_value, CHECK_NULL);
       }
       break;
     }
 
   case JVM_CONSTANT_Integer:
     assert(cache_index == _no_index_sentinel, "should not have been set");
-    prim_value.i = this_oop->int_at(index);
+    prim_value.i = this_cp->int_at(index);
     result_oop = java_lang_boxing_object::create(T_INT, &prim_value, CHECK_NULL);
     break;
 
   case JVM_CONSTANT_Float:
     assert(cache_index == _no_index_sentinel, "should not have been set");
-    prim_value.f = this_oop->float_at(index);
+    prim_value.f = this_cp->float_at(index);
     result_oop = java_lang_boxing_object::create(T_FLOAT, &prim_value, CHECK_NULL);
     break;
 
   case JVM_CONSTANT_Long:
     assert(cache_index == _no_index_sentinel, "should not have been set");
-    prim_value.j = this_oop->long_at(index);
+    prim_value.j = this_cp->long_at(index);
     result_oop = java_lang_boxing_object::create(T_LONG, &prim_value, CHECK_NULL);
     break;
 
   case JVM_CONSTANT_Double:
     assert(cache_index == _no_index_sentinel, "should not have been set");
-    prim_value.d = this_oop->double_at(index);
+    prim_value.d = this_cp->double_at(index);
     result_oop = java_lang_boxing_object::create(T_DOUBLE, &prim_value, CHECK_NULL);
     break;
 
   default:
     DEBUG_ONLY( tty->print_cr("*** %p: tag at CP[%d/%d] = %d",
-                              this_oop(), index, cache_index, tag_value) );
+                              this_cp(), index, cache_index, tag_value) );
     assert(false, "unexpected constant tag");
     break;
   }
@@ -750,15 +750,15 @@
   if (cache_index >= 0) {
     // Cache the oop here also.
     Handle result_handle(THREAD, result_oop);
-    MonitorLockerEx ml(this_oop->lock());  // don't know if we really need this
-    oop result = this_oop->resolved_references()->obj_at(cache_index);
+    MonitorLockerEx ml(this_cp->lock());  // don't know if we really need this
+    oop result = this_cp->resolved_references()->obj_at(cache_index);
     // Benign race condition:  resolved_references may already be filled in while we were trying to lock.
     // The important thing here is that all threads pick up the same result.
     // It doesn't matter which racing thread wins, as long as only one
     // result is used by all threads, and all future queries.
     // That result may be either a resolved constant or a failure exception.
     if (result == NULL) {
-      this_oop->resolved_references()->obj_at_put(cache_index, result_handle());
+      this_cp->resolved_references()->obj_at_put(cache_index, result_handle());
       return result_handle();
     } else {
       // Return the winning thread's result.  This can be different than
@@ -778,8 +778,8 @@
 }
 
 
-oop ConstantPool::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) {
-  assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");
+oop ConstantPool::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_cp, int index, TRAPS) {
+  assert(this_cp->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");
 
   Handle bsm;
   int argc;
@@ -787,14 +787,14 @@
     // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments
     // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.
     // It is accompanied by the optional arguments.
-    int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index);
-    oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL);
+    int bsm_index = this_cp->invoke_dynamic_bootstrap_method_ref_index_at(index);
+    oop bsm_oop = this_cp->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL);
     if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) {
       THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle");
     }
 
     // Extract the optional static arguments.
-    argc = this_oop->invoke_dynamic_argument_count_at(index);
+    argc = this_cp->invoke_dynamic_argument_count_at(index);
     if (argc == 0)  return bsm_oop;
 
     bsm = Handle(THREAD, bsm_oop);
@@ -808,21 +808,21 @@
 
   info->obj_at_put(0, bsm());
   for (int i = 0; i < argc; i++) {
-    int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i);
-    oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL);
+    int arg_index = this_cp->invoke_dynamic_argument_index_at(index, i);
+    oop arg_oop = this_cp->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL);
     info->obj_at_put(1+i, arg_oop);
   }
 
   return info();
 }
 
-oop ConstantPool::string_at_impl(constantPoolHandle this_oop, int which, int obj_index, TRAPS) {
+oop ConstantPool::string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS) {
   // If the string has already been interned, this entry will be non-null
-  oop str = this_oop->resolved_references()->obj_at(obj_index);
+  oop str = this_cp->resolved_references()->obj_at(obj_index);
   if (str != NULL) return str;
-  Symbol* sym = this_oop->unresolved_string_at(which);
+  Symbol* sym = this_cp->unresolved_string_at(which);
   str = StringTable::intern(sym, CHECK_(NULL));
-  this_oop->string_at_put(which, obj_index, str);
+  this_cp->string_at_put(which, obj_index, str);
   assert(java_lang_String::is_instance(str), "must be string");
   return str;
 }
--- a/hotspot/src/share/vm/oops/constantPool.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/constantPool.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -48,7 +48,7 @@
 # include "bytes_ppc.hpp"
 #endif
 
-// A constantPool is an array containing class constants as described in the
+// A ConstantPool is an array containing class constants as described in the
 // class file.
 //
 // Most of the constant pool entries are written during class parsing, which
@@ -81,9 +81,10 @@
 };
 
 class KlassSizeStats;
+
 class ConstantPool : public Metadata {
   friend class VMStructs;
-  friend class BytecodeInterpreter;  // Directly extracts an oop in the pool for fast instanceof/checkcast
+  friend class BytecodeInterpreter;  // Directly extracts a klass in the pool for fast instanceof/checkcast
   friend class Universe;             // For null constructor
  private:
   Array<u1>*           _tags;        // the tag array describing the constant pool's contents
@@ -747,13 +748,13 @@
   friend class SystemDictionary;
 
   // Used by compiler to prevent classloading.
-  static Method*          method_at_if_loaded      (constantPoolHandle this_oop, int which);
-  static bool       has_appendix_at_if_loaded      (constantPoolHandle this_oop, int which);
-  static oop            appendix_at_if_loaded      (constantPoolHandle this_oop, int which);
-  static bool    has_method_type_at_if_loaded      (constantPoolHandle this_oop, int which);
-  static oop         method_type_at_if_loaded      (constantPoolHandle this_oop, int which);
-  static Klass*            klass_at_if_loaded      (constantPoolHandle this_oop, int which);
-  static Klass*        klass_ref_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static Method*          method_at_if_loaded      (constantPoolHandle this_cp, int which);
+  static bool       has_appendix_at_if_loaded      (constantPoolHandle this_cp, int which);
+  static oop            appendix_at_if_loaded      (constantPoolHandle this_cp, int which);
+  static bool    has_method_type_at_if_loaded      (constantPoolHandle this_cp, int which);
+  static oop         method_type_at_if_loaded      (constantPoolHandle this_cp, int which);
+  static Klass*            klass_at_if_loaded      (constantPoolHandle this_cp, int which);
+  static Klass*        klass_ref_at_if_loaded      (constantPoolHandle this_cp, int which);
 
   // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
   // future by other Java code. These take constant pool indices rather than
@@ -811,19 +812,19 @@
   }
 
   // Performs the LinkResolver checks
-  static void verify_constant_pool_resolve(constantPoolHandle this_oop, KlassHandle klass, TRAPS);
+  static void verify_constant_pool_resolve(constantPoolHandle this_cp, KlassHandle klass, TRAPS);
 
   // Implementation of methods that needs an exposed 'this' pointer, in order to
   // handle GC while executing the method
-  static Klass* klass_at_impl(constantPoolHandle this_oop, int which, TRAPS);
-  static oop string_at_impl(constantPoolHandle this_oop, int which, int obj_index, TRAPS);
+  static Klass* klass_at_impl(constantPoolHandle this_cp, int which, TRAPS);
+  static oop string_at_impl(constantPoolHandle this_cp, int which, int obj_index, TRAPS);
 
   // Resolve string constants (to prevent allocation during compilation)
-  static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS);
+  static void resolve_string_constants_impl(constantPoolHandle this_cp, TRAPS);
 
-  static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS);
-  static void save_and_throw_exception(constantPoolHandle this_oop, int which, int tag_value, TRAPS);
-  static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS);
+  static oop resolve_constant_at_impl(constantPoolHandle this_cp, int index, int cache_index, TRAPS);
+  static void save_and_throw_exception(constantPoolHandle this_cp, int which, int tag_value, TRAPS);
+  static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_cp, int index, TRAPS);
 
  public:
   // Merging ConstantPool* support:
--- a/hotspot/src/share/vm/oops/cpCache.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -328,7 +328,7 @@
   // the f1 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
   // not '(Ljava/lang/String;)Ljava/util/List;'.
   // The fact that String and List are involved is encoded in the MethodType in refs[f2].
-  // This allows us to create fewer method oops, while keeping type safety.
+  // This allows us to create fewer Methods, while keeping type safety.
   //
 
   objArrayHandle resolved_references = cpool->resolved_references();
--- a/hotspot/src/share/vm/oops/cpCache.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/cpCache.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -102,8 +102,9 @@
 // _f1      = Method* for non-virtual calls, unused by virtual calls.
 //            for interface calls, which are essentially virtual but need a klass,
 //            contains Klass* for the corresponding interface.
-//            for invokedynamic, f1 contains a site-specific CallSite object (as an appendix)
-//            for invokehandle, f1 contains a site-specific MethodType object (as an appendix)
+//            for invokedynamic and invokehandle, f1 contains the adapter method which
+//            manages the actual call. The appendix is stored in the ConstantPool
+//            resolved_references array.
 //            (upcoming metadata changes will move the appendix to a separate array)
 // _f2      = vtable/itable index (or final Method*) for virtual calls only,
 //            unused by non-virtual.  The is_vfinal flag indicates this is a
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -432,8 +432,8 @@
     if (!InstanceKlass::cast(super)->is_initialized()) return;
 
     // call body to expose the this pointer
-    instanceKlassHandle this_oop(thread, this);
-    eager_initialize_impl(this_oop);
+    instanceKlassHandle this_k(thread, this);
+    eager_initialize_impl(this_k);
   }
 }
 
@@ -470,16 +470,16 @@
   assert(!is_not_initialized(), "class must be initialized now");
 }
 
-void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
+void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_k) {
   EXCEPTION_MARK;
-  oop init_lock = this_oop->init_lock();
+  oop init_lock = this_k->init_lock();
   ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
 
   // abort if someone beat us to the initialization
-  if (!this_oop->is_not_initialized()) return;  // note: not equivalent to is_initialized()
-
-  ClassState old_state = this_oop->init_state();
-  link_class_impl(this_oop, true, THREAD);
+  if (!this_k->is_not_initialized()) return;  // note: not equivalent to is_initialized()
+
+  ClassState old_state = this_k->init_state();
+  link_class_impl(this_k, true, THREAD);
   if (HAS_PENDING_EXCEPTION) {
     CLEAR_PENDING_EXCEPTION;
     // Abort if linking the class throws an exception.
@@ -487,16 +487,16 @@
     // Use a test to avoid redundantly resetting the state if there's
     // no change.  Set_init_state() asserts that state changes make
     // progress, whereas here we might just be spinning in place.
-    if( old_state != this_oop->_init_state )
-      this_oop->set_init_state (old_state);
+    if( old_state != this_k->_init_state )
+      this_k->set_init_state (old_state);
   } else {
     // linking successfull, mark class as initialized
-    this_oop->set_init_state (fully_initialized);
-    this_oop->fence_and_clear_init_lock();
+    this_k->set_init_state (fully_initialized);
+    this_k->fence_and_clear_init_lock();
     // trace
     if (TraceClassInitialization) {
       ResourceMark rm(THREAD);
-      tty->print_cr("[Initialized %s without side effects]", this_oop->external_name());
+      tty->print_cr("[Initialized %s without side effects]", this_k->external_name());
     }
   }
 }
@@ -508,8 +508,8 @@
 void InstanceKlass::initialize(TRAPS) {
   if (this->should_be_initialized()) {
     HandleMark hm(THREAD);
-    instanceKlassHandle this_oop(THREAD, this);
-    initialize_impl(this_oop, CHECK);
+    instanceKlassHandle this_k(THREAD, this);
+    initialize_impl(this_k, CHECK);
     // Note: at this point the class may be initialized
     //       OR it may be in the state of being initialized
     //       in case of recursive initialization!
@@ -520,11 +520,11 @@
 
 
 bool InstanceKlass::verify_code(
-    instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {
+    instanceKlassHandle this_k, bool throw_verifyerror, TRAPS) {
   // 1) Verify the bytecodes
   Verifier::Mode mode =
     throw_verifyerror ? Verifier::ThrowException : Verifier::NoException;
-  return Verifier::verify(this_oop, mode, this_oop->should_verify_class(), CHECK_false);
+  return Verifier::verify(this_k, mode, this_k->should_verify_class(), CHECK_false);
 }
 
 
@@ -540,8 +540,8 @@
   assert(is_loaded(), "must be loaded");
   if (!is_linked()) {
     HandleMark hm(THREAD);
-    instanceKlassHandle this_oop(THREAD, this);
-    link_class_impl(this_oop, true, CHECK);
+    instanceKlassHandle this_k(THREAD, this);
+    link_class_impl(this_k, true, CHECK);
   }
 }
 
@@ -551,22 +551,22 @@
   assert(is_loaded(), "must be loaded");
   if (!is_linked()) {
     HandleMark hm(THREAD);
-    instanceKlassHandle this_oop(THREAD, this);
-    link_class_impl(this_oop, false, CHECK_false);
+    instanceKlassHandle this_k(THREAD, this);
+    link_class_impl(this_k, false, CHECK_false);
   }
   return is_linked();
 }
 
 bool InstanceKlass::link_class_impl(
-    instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS) {
+    instanceKlassHandle this_k, bool throw_verifyerror, TRAPS) {
   // check for error state
-  if (this_oop->is_in_error_state()) {
+  if (this_k->is_in_error_state()) {
     ResourceMark rm(THREAD);
     THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(),
-               this_oop->external_name(), false);
+               this_k->external_name(), false);
   }
   // return if already verified
-  if (this_oop->is_linked()) {
+  if (this_k->is_linked()) {
     return true;
   }
 
@@ -576,7 +576,7 @@
   JavaThread* jt = (JavaThread*)THREAD;
 
   // link super class before linking this class
-  instanceKlassHandle super(THREAD, this_oop->super());
+  instanceKlassHandle super(THREAD, this_k->super());
   if (super.not_null()) {
     if (super->is_interface()) {  // check if super class is an interface
       ResourceMark rm(THREAD);
@@ -584,7 +584,7 @@
         THREAD_AND_LOCATION,
         vmSymbols::java_lang_IncompatibleClassChangeError(),
         "class %s has interface %s as super class",
-        this_oop->external_name(),
+        this_k->external_name(),
         super->external_name()
       );
       return false;
@@ -594,7 +594,7 @@
   }
 
   // link all interfaces implemented by this class before linking this class
-  Array<Klass*>* interfaces = this_oop->local_interfaces();
+  Array<Klass*>* interfaces = this_k->local_interfaces();
   int num_interfaces = interfaces->length();
   for (int index = 0; index < num_interfaces; index++) {
     HandleMark hm(THREAD);
@@ -603,7 +603,7 @@
   }
 
   // in case the class is linked in the process of linking its superclasses
-  if (this_oop->is_linked()) {
+  if (this_k->is_linked()) {
     return true;
   }
 
@@ -618,14 +618,14 @@
 
   // verification & rewriting
   {
-    oop init_lock = this_oop->init_lock();
+    oop init_lock = this_k->init_lock();
     ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
     // rewritten will have been set if loader constraint error found
     // on an earlier link attempt
     // don't verify or rewrite if already rewritten
 
-    if (!this_oop->is_linked()) {
-      if (!this_oop->is_rewritten()) {
+    if (!this_k->is_linked()) {
+      if (!this_k->is_rewritten()) {
         {
           // Timer includes any side effects of class verification (resolution,
           // etc), but not recursive entry into verify_code().
@@ -635,7 +635,7 @@
                                    jt->get_thread_stat()->perf_recursion_counts_addr(),
                                    jt->get_thread_stat()->perf_timers_addr(),
                                    PerfClassTraceTime::CLASS_VERIFY);
-          bool verify_ok = verify_code(this_oop, throw_verifyerror, THREAD);
+          bool verify_ok = verify_code(this_k, throw_verifyerror, THREAD);
           if (!verify_ok) {
             return false;
           }
@@ -644,39 +644,39 @@
         // Just in case a side-effect of verify linked this class already
         // (which can sometimes happen since the verifier loads classes
         // using custom class loaders, which are free to initialize things)
-        if (this_oop->is_linked()) {
+        if (this_k->is_linked()) {
           return true;
         }
 
         // also sets rewritten
-        this_oop->rewrite_class(CHECK_false);
+        this_k->rewrite_class(CHECK_false);
       }
 
       // relocate jsrs and link methods after they are all rewritten
-      this_oop->link_methods(CHECK_false);
+      this_k->link_methods(CHECK_false);
 
       // Initialize the vtable and interface table after
       // methods have been rewritten since rewrite may
       // fabricate new Method*s.
       // also does loader constraint checking
-      if (!this_oop()->is_shared()) {
+      if (!this_k()->is_shared()) {
         ResourceMark rm(THREAD);
-        this_oop->vtable()->initialize_vtable(true, CHECK_false);
-        this_oop->itable()->initialize_itable(true, CHECK_false);
+        this_k->vtable()->initialize_vtable(true, CHECK_false);
+        this_k->itable()->initialize_itable(true, CHECK_false);
       }
 #ifdef ASSERT
       else {
         ResourceMark rm(THREAD);
-        this_oop->vtable()->verify(tty, true);
+        this_k->vtable()->verify(tty, true);
         // In case itable verification is ever added.
-        // this_oop->itable()->verify(tty, true);
+        // this_k->itable()->verify(tty, true);
       }
 #endif
-      this_oop->set_init_state(linked);
+      this_k->set_init_state(linked);
       if (JvmtiExport::should_post_class_prepare()) {
         Thread *thread = THREAD;
         assert(thread->is_Java_thread(), "thread->is_Java_thread()");
-        JvmtiExport::post_class_prepare((JavaThread *) thread, this_oop());
+        JvmtiExport::post_class_prepare((JavaThread *) thread, this_k());
       }
     }
   }
@@ -689,13 +689,13 @@
 // verification but before the first method of the class is executed.
 void InstanceKlass::rewrite_class(TRAPS) {
   assert(is_loaded(), "must be loaded");
-  instanceKlassHandle this_oop(THREAD, this);
-  if (this_oop->is_rewritten()) {
-    assert(this_oop()->is_shared(), "rewriting an unshared class?");
+  instanceKlassHandle this_k(THREAD, this);
+  if (this_k->is_rewritten()) {
+    assert(this_k()->is_shared(), "rewriting an unshared class?");
     return;
   }
-  Rewriter::rewrite(this_oop, CHECK);
-  this_oop->set_rewritten();
+  Rewriter::rewrite(this_k, CHECK);
+  this_k->set_rewritten();
 }
 
 // Now relocate and link method entry points after class is rewritten.
@@ -729,19 +729,19 @@
 }
 
 
-void InstanceKlass::initialize_impl(instanceKlassHandle this_oop, TRAPS) {
+void InstanceKlass::initialize_impl(instanceKlassHandle this_k, TRAPS) {
   // Make sure klass is linked (verified) before initialization
   // A class could already be verified, since it has been reflected upon.
-  this_oop->link_class(CHECK);
-
-  DTRACE_CLASSINIT_PROBE(required, InstanceKlass::cast(this_oop()), -1);
+  this_k->link_class(CHECK);
+
+  DTRACE_CLASSINIT_PROBE(required, InstanceKlass::cast(this_k()), -1);
 
   bool wait = false;
 
   // refer to the JVM book page 47 for description of steps
   // Step 1
   {
-    oop init_lock = this_oop->init_lock();
+    oop init_lock = this_k->init_lock();
     ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
 
     Thread *self = THREAD; // it's passed the current thread
@@ -750,29 +750,29 @@
     // If we were to use wait() instead of waitInterruptibly() then
     // we might end up throwing IE from link/symbol resolution sites
     // that aren't expected to throw.  This would wreak havoc.  See 6320309.
-    while(this_oop->is_being_initialized() && !this_oop->is_reentrant_initialization(self)) {
+    while(this_k->is_being_initialized() && !this_k->is_reentrant_initialization(self)) {
         wait = true;
       ol.waitUninterruptibly(CHECK);
     }
 
     // Step 3
-    if (this_oop->is_being_initialized() && this_oop->is_reentrant_initialization(self)) {
-      DTRACE_CLASSINIT_PROBE_WAIT(recursive, InstanceKlass::cast(this_oop()), -1,wait);
+    if (this_k->is_being_initialized() && this_k->is_reentrant_initialization(self)) {
+      DTRACE_CLASSINIT_PROBE_WAIT(recursive, InstanceKlass::cast(this_k()), -1,wait);
       return;
     }
 
     // Step 4
-    if (this_oop->is_initialized()) {
-      DTRACE_CLASSINIT_PROBE_WAIT(concurrent, InstanceKlass::cast(this_oop()), -1,wait);
+    if (this_k->is_initialized()) {
+      DTRACE_CLASSINIT_PROBE_WAIT(concurrent, InstanceKlass::cast(this_k()), -1,wait);
       return;
     }
 
     // Step 5
-    if (this_oop->is_in_error_state()) {
-      DTRACE_CLASSINIT_PROBE_WAIT(erroneous, InstanceKlass::cast(this_oop()), -1,wait);
+    if (this_k->is_in_error_state()) {
+      DTRACE_CLASSINIT_PROBE_WAIT(erroneous, InstanceKlass::cast(this_k()), -1,wait);
       ResourceMark rm(THREAD);
       const char* desc = "Could not initialize class ";
-      const char* className = this_oop->external_name();
+      const char* className = this_k->external_name();
       size_t msglen = strlen(desc) + strlen(className) + 1;
       char* message = NEW_RESOURCE_ARRAY(char, msglen);
       if (NULL == message) {
@@ -785,13 +785,13 @@
     }
 
     // Step 6
-    this_oop->set_init_state(being_initialized);
-    this_oop->set_init_thread(self);
+    this_k->set_init_state(being_initialized);
+    this_k->set_init_thread(self);
   }
 
   // Step 7
-  Klass* super_klass = this_oop->super();
-  if (super_klass != NULL && !this_oop->is_interface() && super_klass->should_be_initialized()) {
+  Klass* super_klass = this_k->super();
+  if (super_klass != NULL && !this_k->is_interface() && super_klass->should_be_initialized()) {
     super_klass->initialize(THREAD);
 
     if (HAS_PENDING_EXCEPTION) {
@@ -799,18 +799,18 @@
       CLEAR_PENDING_EXCEPTION;
       {
         EXCEPTION_MARK;
-        this_oop->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
+        this_k->set_initialization_state_and_notify(initialization_error, THREAD); // Locks object, set state, and notify all waiting threads
         CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, superclass initialization error is thrown below
       }
-      DTRACE_CLASSINIT_PROBE_WAIT(super__failed, InstanceKlass::cast(this_oop()), -1,wait);
+      DTRACE_CLASSINIT_PROBE_WAIT(super__failed, InstanceKlass::cast(this_k()), -1,wait);
       THROW_OOP(e());
     }
   }
 
-  if (this_oop->has_default_methods()) {
+  if (this_k->has_default_methods()) {
     // Step 7.5: initialize any interfaces which have default methods
-    for (int i = 0; i < this_oop->local_interfaces()->length(); ++i) {
-      Klass* iface = this_oop->local_interfaces()->at(i);
+    for (int i = 0; i < this_k->local_interfaces()->length(); ++i) {
+      Klass* iface = this_k->local_interfaces()->at(i);
       InstanceKlass* ik = InstanceKlass::cast(iface);
       if (ik->has_default_methods() && ik->should_be_initialized()) {
         ik->initialize(THREAD);
@@ -821,7 +821,7 @@
           {
             EXCEPTION_MARK;
             // Locks object, set state, and notify all waiting threads
-            this_oop->set_initialization_state_and_notify(
+            this_k->set_initialization_state_and_notify(
                 initialization_error, THREAD);
 
             // ignore any exception thrown, superclass initialization error is
@@ -829,7 +829,7 @@
             CLEAR_PENDING_EXCEPTION;
           }
           DTRACE_CLASSINIT_PROBE_WAIT(
-              super__failed, InstanceKlass::cast(this_oop()), -1, wait);
+              super__failed, InstanceKlass::cast(this_k()), -1, wait);
           THROW_OOP(e());
         }
       }
@@ -840,7 +840,7 @@
   {
     assert(THREAD->is_Java_thread(), "non-JavaThread in initialize_impl");
     JavaThread* jt = (JavaThread*)THREAD;
-    DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_oop()), -1,wait);
+    DTRACE_CLASSINIT_PROBE_WAIT(clinit, InstanceKlass::cast(this_k()), -1,wait);
     // Timer includes any side effects of class initialization (resolution,
     // etc), but not recursive entry into call_class_initializer().
     PerfClassTraceTime timer(ClassLoader::perf_class_init_time(),
@@ -849,14 +849,14 @@
                              jt->get_thread_stat()->perf_recursion_counts_addr(),
                              jt->get_thread_stat()->perf_timers_addr(),
                              PerfClassTraceTime::CLASS_CLINIT);
-    this_oop->call_class_initializer(THREAD);
+    this_k->call_class_initializer(THREAD);
   }
 
   // Step 9
   if (!HAS_PENDING_EXCEPTION) {
-    this_oop->set_initialization_state_and_notify(fully_initialized, CHECK);
+    this_k->set_initialization_state_and_notify(fully_initialized, CHECK);
     { ResourceMark rm(THREAD);
-      debug_only(this_oop->vtable()->verify(tty, true);)
+      debug_only(this_k->vtable()->verify(tty, true);)
     }
   }
   else {
@@ -868,13 +868,13 @@
     JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
     {
       EXCEPTION_MARK;
-      this_oop->set_initialization_state_and_notify(initialization_error, THREAD);
+      this_k->set_initialization_state_and_notify(initialization_error, THREAD);
       CLEAR_PENDING_EXCEPTION;   // ignore any exception thrown, class initialization error is thrown below
       // JVMTI has already reported the pending exception
       // JVMTI internal flag reset is needed in order to report ExceptionInInitializerError
       JvmtiExport::clear_detected_exception((JavaThread*)THREAD);
     }
-    DTRACE_CLASSINIT_PROBE_WAIT(error, InstanceKlass::cast(this_oop()), -1,wait);
+    DTRACE_CLASSINIT_PROBE_WAIT(error, InstanceKlass::cast(this_k()), -1,wait);
     if (e->is_a(SystemDictionary::Error_klass())) {
       THROW_OOP(e());
     } else {
@@ -884,7 +884,7 @@
                 &args);
     }
   }
-  DTRACE_CLASSINIT_PROBE_WAIT(end, InstanceKlass::cast(this_oop()), -1,wait);
+  DTRACE_CLASSINIT_PROBE_WAIT(end, InstanceKlass::cast(this_k()), -1,wait);
 }
 
 
@@ -894,11 +894,11 @@
   set_initialization_state_and_notify_impl(kh, state, CHECK);
 }
 
-void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_oop, ClassState state, TRAPS) {
-  oop init_lock = this_oop->init_lock();
+void InstanceKlass::set_initialization_state_and_notify_impl(instanceKlassHandle this_k, ClassState state, TRAPS) {
+  oop init_lock = this_k->init_lock();
   ObjectLocker ol(init_lock, THREAD, init_lock != NULL);
-  this_oop->set_init_state(state);
-  this_oop->fence_and_clear_init_lock();
+  this_k->set_init_state(state);
+  this_k->fence_and_clear_init_lock();
   ol.notify_all(CHECK);
 }
 
@@ -952,12 +952,11 @@
 
 void InstanceKlass::process_interfaces(Thread *thread) {
   // link this class into the implementors list of every interface it implements
-  Klass* this_as_klass_oop = this;
   for (int i = local_interfaces()->length() - 1; i >= 0; i--) {
     assert(local_interfaces()->at(i)->is_klass(), "must be a klass");
     InstanceKlass* interf = InstanceKlass::cast(local_interfaces()->at(i));
     assert(interf->is_interface(), "expected interface");
-    interf->add_implementor(this_as_klass_oop);
+    interf->add_implementor(this);
   }
 }
 
@@ -1083,12 +1082,12 @@
 }
 
 Klass* InstanceKlass::array_klass_impl(bool or_null, int n, TRAPS) {
-  instanceKlassHandle this_oop(THREAD, this);
-  return array_klass_impl(this_oop, or_null, n, THREAD);
+  instanceKlassHandle this_k(THREAD, this);
+  return array_klass_impl(this_k, or_null, n, THREAD);
 }
 
-Klass* InstanceKlass::array_klass_impl(instanceKlassHandle this_oop, bool or_null, int n, TRAPS) {
-  if (this_oop->array_klasses() == NULL) {
+Klass* InstanceKlass::array_klass_impl(instanceKlassHandle this_k, bool or_null, int n, TRAPS) {
+  if (this_k->array_klasses() == NULL) {
     if (or_null) return NULL;
 
     ResourceMark rm;
@@ -1099,14 +1098,14 @@
       MutexLocker ma(MultiArray_lock, THREAD);
 
       // Check if update has already taken place
-      if (this_oop->array_klasses() == NULL) {
-        Klass*    k = ObjArrayKlass::allocate_objArray_klass(this_oop->class_loader_data(), 1, this_oop, CHECK_NULL);
-        this_oop->set_array_klasses(k);
+      if (this_k->array_klasses() == NULL) {
+        Klass*    k = ObjArrayKlass::allocate_objArray_klass(this_k->class_loader_data(), 1, this_k, CHECK_NULL);
+        this_k->set_array_klasses(k);
       }
     }
   }
   // _this will always be set at this point
-  ObjArrayKlass* oak = (ObjArrayKlass*)this_oop->array_klasses();
+  ObjArrayKlass* oak = (ObjArrayKlass*)this_k->array_klasses();
   if (or_null) {
     return oak->array_klass_or_null(n);
   }
@@ -1133,20 +1132,20 @@
   return NULL;
 }
 
-void InstanceKlass::call_class_initializer_impl(instanceKlassHandle this_oop, TRAPS) {
+void InstanceKlass::call_class_initializer_impl(instanceKlassHandle this_k, TRAPS) {
   if (ReplayCompiles &&
       (ReplaySuppressInitializers == 1 ||
-       ReplaySuppressInitializers >= 2 && this_oop->class_loader() != NULL)) {
+       ReplaySuppressInitializers >= 2 && this_k->class_loader() != NULL)) {
     // Hide the existence of the initializer for the purpose of replaying the compile
     return;
   }
 
-  methodHandle h_method(THREAD, this_oop->class_initializer());
-  assert(!this_oop->is_initialized(), "we cannot initialize twice");
+  methodHandle h_method(THREAD, this_k->class_initializer());
+  assert(!this_k->is_initialized(), "we cannot initialize twice");
   if (TraceClassInitialization) {
     tty->print("%d Initializing ", call_class_initializer_impl_counter++);
-    this_oop->name()->print_value();
-    tty->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", (address)this_oop());
+    this_k->name()->print_value();
+    tty->print_cr("%s (" INTPTR_FORMAT ")", h_method() == NULL ? "(no method)" : "", (address)this_k());
   }
   if (h_method() != NULL) {
     JavaCallArguments args; // No arguments
@@ -1296,8 +1295,8 @@
 }
 
 
-void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS) {
-  for (JavaFieldStream fs(this_oop()); !fs.done(); fs.next()) {
+void InstanceKlass::do_local_static_fields_impl(instanceKlassHandle this_k, void f(fieldDescriptor* fd, TRAPS), TRAPS) {
+  for (JavaFieldStream fs(this_k()); !fs.done(); fs.next()) {
     if (fs.access_flags().is_static()) {
       fieldDescriptor& fd = fs.field_descriptor();
       f(&fd, CHECK);
@@ -1515,14 +1514,14 @@
 }
 
 /* jni_id_for_impl for jfieldIds only */
-JNIid* InstanceKlass::jni_id_for_impl(instanceKlassHandle this_oop, int offset) {
+JNIid* InstanceKlass::jni_id_for_impl(instanceKlassHandle this_k, int offset) {
   MutexLocker ml(JfieldIdCreation_lock);
   // Retry lookup after we got the lock
-  JNIid* probe = this_oop->jni_ids() == NULL ? NULL : this_oop->jni_ids()->find(offset);
+  JNIid* probe = this_k->jni_ids() == NULL ? NULL : this_k->jni_ids()->find(offset);
   if (probe == NULL) {
     // Slow case, allocate new static field identifier
-    probe = new JNIid(this_oop(), offset, this_oop->jni_ids());
-    this_oop->set_jni_ids(probe);
+    probe = new JNIid(this_k(), offset, this_k->jni_ids());
+    this_k->set_jni_ids(probe);
   }
   return probe;
 }
@@ -3161,8 +3160,8 @@
   }
 
   // Verify first subklass
-  if (subklass_oop() != NULL) {
-    guarantee(subklass_oop()->is_klass(), "should be klass");
+  if (subklass() != NULL) {
+    guarantee(subklass()->is_klass(), "should be klass");
   }
 
   // Verify siblings
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -43,35 +43,7 @@
 // An InstanceKlass is the VM level representation of a Java class.
 // It contains all information needed for at class at execution runtime.
 
-//  InstanceKlass layout:
-//    [C++ vtbl pointer           ] Klass
-//    [subtype cache              ] Klass
-//    [instance size              ] Klass
-//    [java mirror                ] Klass
-//    [super                      ] Klass
-//    [access_flags               ] Klass
-//    [name                       ] Klass
-//    [first subklass             ] Klass
-//    [next sibling               ] Klass
-//    [array klasses              ]
-//    [methods                    ]
-//    [local interfaces           ]
-//    [transitive interfaces      ]
-//    [fields                     ]
-//    [constants                  ]
-//    [class loader               ]
-//    [source file name           ]
-//    [inner classes              ]
-//    [static field size          ]
-//    [nonstatic field size       ]
-//    [static oop fields size     ]
-//    [nonstatic oop maps size    ]
-//    [has finalize method        ]
-//    [deoptimization mark bit    ]
-//    [initialization state       ]
-//    [initializing thread        ]
-//    [Java vtable length         ]
-//    [oop map cache (stack maps) ]
+//  InstanceKlass embedded field layout (after declared fields):
 //    [EMBEDDED Java vtable             ] size in words = vtable_len
 //    [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size
 //      The embedded nonstatic oop-map blocks are short pairs (offset, length)
@@ -1031,16 +1003,16 @@
 
   // Static methods that are used to implement member methods where an exposed this pointer
   // is needed due to possible GCs
-  static bool link_class_impl                           (instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS);
-  static bool verify_code                               (instanceKlassHandle this_oop, bool throw_verifyerror, TRAPS);
-  static void initialize_impl                           (instanceKlassHandle this_oop, TRAPS);
-  static void eager_initialize_impl                     (instanceKlassHandle this_oop);
-  static void set_initialization_state_and_notify_impl  (instanceKlassHandle this_oop, ClassState state, TRAPS);
-  static void call_class_initializer_impl               (instanceKlassHandle this_oop, TRAPS);
-  static Klass* array_klass_impl                      (instanceKlassHandle this_oop, bool or_null, int n, TRAPS);
-  static void do_local_static_fields_impl               (instanceKlassHandle this_oop, void f(fieldDescriptor* fd, TRAPS), TRAPS);
+  static bool link_class_impl                           (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS);
+  static bool verify_code                               (instanceKlassHandle this_k, bool throw_verifyerror, TRAPS);
+  static void initialize_impl                           (instanceKlassHandle this_k, TRAPS);
+  static void eager_initialize_impl                     (instanceKlassHandle this_k);
+  static void set_initialization_state_and_notify_impl  (instanceKlassHandle this_k, ClassState state, TRAPS);
+  static void call_class_initializer_impl               (instanceKlassHandle this_k, TRAPS);
+  static Klass* array_klass_impl                        (instanceKlassHandle this_k, bool or_null, int n, TRAPS);
+  static void do_local_static_fields_impl               (instanceKlassHandle this_k, void f(fieldDescriptor* fd, TRAPS), TRAPS);
   /* jni_id_for_impl for jfieldID only */
-  static JNIid* jni_id_for_impl                         (instanceKlassHandle this_oop, int offset);
+  static JNIid* jni_id_for_impl                         (instanceKlassHandle this_k, int offset);
 
   // Returns the array class for the n'th dimension
   Klass* array_klass_impl(bool or_null, int n, TRAPS);
--- a/hotspot/src/share/vm/oops/klass.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/klass.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -334,19 +334,11 @@
 }
 
 
-Klass* Klass::subklass() const {
-  return _subklass == NULL ? NULL : _subklass;
-}
-
 InstanceKlass* Klass::superklass() const {
   assert(super() == NULL || super()->oop_is_instance(), "must be instance klass");
   return _super == NULL ? NULL : InstanceKlass::cast(_super);
 }
 
-Klass* Klass::next_sibling() const {
-  return _next_sibling == NULL ? NULL : _next_sibling;
-}
-
 void Klass::set_subklass(Klass* s) {
   assert(s != this, "sanity check");
   _subklass = s;
@@ -365,7 +357,7 @@
   assert((!super->is_interface()    // interfaces cannot be supers
           && (super->superklass() == NULL || !is_interface())),
          "an interface can only be a subklass of Object");
-  Klass* prev_first_subklass = super->subklass_oop();
+  Klass* prev_first_subklass = super->subklass();
   if (prev_first_subklass != NULL) {
     // set our sibling to be the superklass' previous first subklass
     set_next_sibling(prev_first_subklass);
@@ -405,7 +397,7 @@
     assert(current->is_loader_alive(is_alive), "just checking, this should be live");
 
     // Find and set the first alive subklass
-    Klass* sub = current->subklass_oop();
+    Klass* sub = current->subklass();
     while (sub != NULL && !sub->is_loader_alive(is_alive)) {
 #ifndef PRODUCT
       if (TraceClassUnloading && WizardMode) {
@@ -413,7 +405,7 @@
         tty->print_cr("[Unlinking class (subclass) %s]", sub->external_name());
       }
 #endif
-      sub = sub->next_sibling_oop();
+      sub = sub->next_sibling();
     }
     current->set_subklass(sub);
     if (sub != NULL) {
@@ -421,13 +413,13 @@
     }
 
     // Find and set the first alive sibling
-    Klass* sibling = current->next_sibling_oop();
+    Klass* sibling = current->next_sibling();
     while (sibling != NULL && !sibling->is_loader_alive(is_alive)) {
       if (TraceClassUnloading && WizardMode) {
         ResourceMark rm;
         tty->print_cr("[Unlinking class (sibling) %s]", sibling->external_name());
       }
-      sibling = sibling->next_sibling_oop();
+      sibling = sibling->next_sibling();
     }
     current->set_next_sibling(sibling);
     if (sibling != NULL) {
--- a/hotspot/src/share/vm/oops/klass.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/klass.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -56,34 +56,6 @@
 // actual type.  (See oop.inline.hpp for some of the forwarding code.)
 // ALL FUNCTIONS IMPLEMENTING THIS DISPATCH ARE PREFIXED WITH "oop_"!
 
-//  Klass layout:
-//    [C++ vtbl ptr  ] (contained in Metadata)
-//    [layout_helper ]
-//    [super_check_offset   ] for fast subtype checks
-//    [name          ]
-//    [secondary_super_cache] for fast subtype checks
-//    [secondary_supers     ] array of 2ndary supertypes
-//    [primary_supers 0]
-//    [primary_supers 1]
-//    [primary_supers 2]
-//    ...
-//    [primary_supers 7]
-//    [java_mirror   ]
-//    [super         ]
-//    [subklass      ] first subclass
-//    [next_sibling  ] link to chain additional subklasses
-//    [next_link     ]
-//    [class_loader_data]
-//    [modifier_flags]
-//    [access_flags  ]
-//    [last_biased_lock_bulk_revocation_time] (64 bits)
-//    [prototype_header]
-//    [biased_lock_revocation_count]
-//    [_modified_oops]
-//    [_accumulated_modified_oops]
-//    [trace_id]
-
-
 // Forward declarations.
 template <class T> class Array;
 template <class T> class GrowableArray;
@@ -257,9 +229,9 @@
   // Use InstanceKlass::contains_field_offset to classify field offsets.
 
   // sub/superklass links
+  Klass* subklass() const              { return _subklass; }
+  Klass* next_sibling() const          { return _next_sibling; }
   InstanceKlass* superklass() const;
-  Klass* subklass() const;
-  Klass* next_sibling() const;
   void append_to_sibling_list();           // add newly created receiver to superklass' subklass list
 
   void set_next_link(Klass* k) { _next_link = k; }
@@ -281,8 +253,6 @@
   bool has_accumulated_modified_oops()   { return _accumulated_modified_oops == 1; }
 
  protected:                                // internal accessors
-  Klass* subklass_oop() const            { return _subklass; }
-  Klass* next_sibling_oop() const        { return _next_sibling; }
   void     set_subklass(Klass* s);
   void     set_next_sibling(Klass* s);
 
--- a/hotspot/src/share/vm/oops/method.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/method.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -577,12 +577,12 @@
 }
 
 
-objArrayHandle Method::resolved_checked_exceptions_impl(Method* this_oop, TRAPS) {
-  int length = this_oop->checked_exceptions_length();
+objArrayHandle Method::resolved_checked_exceptions_impl(Method* method, TRAPS) {
+  int length = method->checked_exceptions_length();
   if (length == 0) {  // common case
     return objArrayHandle(THREAD, Universe::the_empty_class_klass_array());
   } else {
-    methodHandle h_this(THREAD, this_oop);
+    methodHandle h_this(THREAD, method);
     objArrayOop m_oop = oopFactory::new_objArray(SystemDictionary::Class_klass(), length, CHECK_(objArrayHandle()));
     objArrayHandle mirrors (THREAD, m_oop);
     for (int i = 0; i < length; i++) {
--- a/hotspot/src/share/vm/oops/method.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/oops/method.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -40,50 +40,15 @@
 
 // A Method represents a Java method.
 //
-// Memory layout (each line represents a word). Note that most applications load thousands of methods,
-// so keeping the size of this structure small has a big impact on footprint.
-//
-// The actual bytecodes are inlined after the end of the Method struct.
-//
-// There are bits in the access_flags telling whether inlined tables are present.
-// Note that accessing the line number and local variable tables is not performance critical at all.
-// Accessing the checked exceptions table is used by reflection, so we put that last to make access
-// to it fast.
-//
-// The line number table is compressed and inlined following the byte codes. It is found as the first
-// byte following the byte codes. The checked exceptions table and the local variable table are inlined
-// after the line number table, and indexed from the end of the method. We do not compress the checked
-// exceptions table since the average length is less than 2, and do not bother to compress the local
-// variable table either since it is mostly absent.
-//
-// Note that native_function and signature_handler has to be at fixed offsets (required by the interpreter)
+// Note that most applications load thousands of methods, so keeping the size of this
+// class small has a big impact on footprint.
 //
-// |------------------------------------------------------|
-// | header                                               |
-// | klass                                                |
-// |------------------------------------------------------|
-// | ConstMethod*                   (metadata)            |
-// |------------------------------------------------------|
-// | MethodData*                    (metadata)            |
-// | MethodCounters                                       |
-// |------------------------------------------------------|
-// | access_flags                                         |
-// | vtable_index                                         |
-// |------------------------------------------------------|
-// | result_index (C++ interpreter only)                  |
-// |------------------------------------------------------|
-// | method_size             | intrinsic_id  |   flags    |
-// |------------------------------------------------------|
-// | code                           (pointer)             |
-// | i2i                            (pointer)             |
-// | adapter                        (pointer)             |
-// | from_compiled_entry            (pointer)             |
-// | from_interpreted_entry         (pointer)             |
-// |------------------------------------------------------|
-// | native_function       (present only if native)       |
-// | signature_handler     (present only if native)       |
-// |------------------------------------------------------|
-
+// Note that native_function and signature_handler have to be at fixed offsets
+// (required by the interpreter)
+//
+//  Method embedded field layout (after declared fields):
+//   [EMBEDDED native_function       (present only if native) ]
+//   [EMBEDDED signature_handler     (present only if native) ]
 
 class CheckedExceptionElement;
 class LocalVariableTableElement;
@@ -661,7 +626,7 @@
 
   // Static methods that are used to implement member methods where an exposed this pointer
   // is needed due to possible GCs
-  static objArrayHandle resolved_checked_exceptions_impl(Method* this_oop, TRAPS);
+  static objArrayHandle resolved_checked_exceptions_impl(Method* method, TRAPS);
 
   // Returns the byte code index from the byte code pointer
   int     bci_from(address bcp) const;
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -1020,19 +1020,12 @@
     }
 
     if (owning_thread != NULL) {  // monitor is owned
-      if ((address)owning_thread == owner) {
-        // the owner field is the JavaThread *
-        assert(mon != NULL,
-          "must have heavyweight monitor with JavaThread * owner");
-        ret.entry_count = mon->recursions() + 1;
-      } else {
-        // The owner field is the Lock word on the JavaThread's stack
-        // so the recursions field is not valid. We have to count the
-        // number of recursive monitor entries the hard way. We pass
-        // a handle to survive any GCs along the way.
-        ResourceMark rm;
-        ret.entry_count = count_locked_objects(owning_thread, hobj);
-      }
+      // The recursions field of a monitor does not reflect recursions
+      // as lightweight locks before inflating the monitor are not included.
+      // We have to count the number of recursive monitor entries the hard way.
+      // We pass a handle to survive any GCs along the way.
+      ResourceMark rm;
+      ret.entry_count = count_locked_objects(owning_thread, hobj);
     }
     // implied else: entry_count == 0
   }
--- a/hotspot/src/share/vm/runtime/arguments.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1903,24 +1903,22 @@
 // check if do gclog rotation
 // +UseGCLogFileRotation is a must,
 // no gc log rotation when log file not supplied or
-// NumberOfGCLogFiles is 0, or GCLogFileSize is 0
+// NumberOfGCLogFiles is 0
 void check_gclog_consistency() {
   if (UseGCLogFileRotation) {
-    if ((Arguments::gc_log_filename() == NULL) ||
-        (NumberOfGCLogFiles == 0)  ||
-        (GCLogFileSize == 0)) {
+    if ((Arguments::gc_log_filename() == NULL) || (NumberOfGCLogFiles == 0)) {
       jio_fprintf(defaultStream::output_stream(),
-                  "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files> -XX:GCLogFileSize=<num_of_size>[k|K|m|M|g|G]\n"
-                  "where num_of_file > 0 and num_of_size > 0\n"
+                  "To enable GC log rotation, use -Xloggc:<filename> -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=<num_of_files>\n"
+                  "where num_of_file > 0\n"
                   "GC log rotation is turned off\n");
       UseGCLogFileRotation = false;
     }
   }
 
-  if (UseGCLogFileRotation && GCLogFileSize < 8*K) {
-        FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
-        jio_fprintf(defaultStream::output_stream(),
-                    "GCLogFileSize changed to minimum 8K\n");
+  if (UseGCLogFileRotation && (GCLogFileSize != 0) && (GCLogFileSize < 8*K)) {
+    FLAG_SET_CMDLINE(uintx, GCLogFileSize, 8*K);
+    jio_fprintf(defaultStream::output_stream(),
+                "GCLogFileSize changed to minimum 8K\n");
   }
 }
 
--- a/hotspot/src/share/vm/runtime/globals.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -2423,9 +2423,9 @@
           "Number of gclog files in rotation "                              \
           "(default: 0, no rotation)")                                      \
                                                                             \
-  product(uintx, GCLogFileSize, 0,                                          \
-          "GC log file size (default: 0 bytes, no rotation). "              \
-          "It requires UseGCLogFileRotation")                               \
+  product(uintx, GCLogFileSize, 8*K,                                        \
+          "GC log file size, requires UseGCLogFileRotation. "               \
+          "Set to 0 to only trigger rotation via jcmd")                     \
                                                                             \
   /* JVMTI heap profiling */                                                \
                                                                             \
--- a/hotspot/src/share/vm/runtime/safepoint.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -535,7 +535,7 @@
 
   // rotate log files?
   if (UseGCLogFileRotation) {
-    gclog_or_tty->rotate_log();
+    gclog_or_tty->rotate_log(false);
   }
 
   if (MemTracker::is_on()) {
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -96,6 +96,7 @@
   template(JFRCheckpoint)                         \
   template(Exit)                                  \
   template(LinuxDllLoad)                          \
+  template(RotateGCLog)                           \
 
 class VM_Operation: public CHeapObj<mtInternal> {
  public:
@@ -399,4 +400,15 @@
   void doit();
 };
 
+
+class VM_RotateGCLog: public VM_Operation {
+ private:
+  outputStream* _out;
+
+ public:
+  VM_RotateGCLog(outputStream* st) : _out(st) {}
+  VMOp_Type type() const { return VMOp_RotateGCLog; }
+  void doit() { gclog_or_tty->rotate_log(true, _out); }
+};
+
 #endif // SHARE_VM_RUNTIME_VM_OPERATIONS_HPP
--- a/hotspot/src/share/vm/services/diagnosticCommand.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/services/diagnosticCommand.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -55,6 +55,7 @@
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ClassStatsDCmd>(full_export, true, false));
 #endif // INCLUDE_SERVICES
   DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<ThreadDumpDCmd>(full_export, true, false));
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<RotateGCLogDCmd>(full_export, true, false));
 
   // Enhanced JMX Agent Support
   // These commands won't be exported via the DiagnosticCommandMBean until an
@@ -659,3 +660,13 @@
   os::print_dll_info(output());
   output()->cr();
 }
+
+void RotateGCLogDCmd::execute(DCmdSource source, TRAPS) {
+  if (UseGCLogFileRotation) {
+    VM_RotateGCLog rotateop(output());
+    VMThread::execute(&rotateop);
+  } else {
+    output()->print_cr("Target VM does not support GC log file rotation.");
+  }
+}
+
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -383,4 +383,21 @@
   virtual void execute(DCmdSource source, TRAPS);
 };
 
+class RotateGCLogDCmd : public DCmd {
+public:
+  RotateGCLogDCmd(outputStream* output, bool heap) : DCmd(output, heap) {}
+  static const char* name() { return "GC.rotate_log"; }
+  static const char* description() {
+    return "Force the GC log file to be rotated.";
+  }
+  static const char* impact() { return "Low"; }
+  virtual void execute(DCmdSource source, TRAPS);
+  static int num_arguments() { return 0; }
+  static const JavaPermission permission() {
+    JavaPermission p = {"java.lang.management.ManagementPermission",
+                        "control", NULL};
+    return p;
+  }
+};
+
 #endif // SHARE_VM_SERVICES_DIAGNOSTICCOMMAND_HPP
--- a/hotspot/src/share/vm/utilities/debug.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/utilities/debug.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -243,7 +243,6 @@
 
 // out of shared space reporting
 enum SharedSpaceType {
-  SharedPermGen,
   SharedReadOnly,
   SharedReadWrite,
   SharedMiscData
--- a/hotspot/src/share/vm/utilities/ostream.cpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.cpp	Sun Mar 30 03:29:48 2014 -0700
@@ -662,13 +662,13 @@
 // write to gc log file at safepoint. If in future, changes made for mutator threads or
 // concurrent GC threads to run parallel with VMThread at safepoint, write and rotate_log
 // must be synchronized.
-void gcLogFileStream::rotate_log() {
+void gcLogFileStream::rotate_log(bool force, outputStream* out) {
   char time_msg[FILENAMEBUFLEN];
   char time_str[EXTRACHARLEN];
   char current_file_name[FILENAMEBUFLEN];
   char renamed_file_name[FILENAMEBUFLEN];
 
-  if (_bytes_written < (jlong)GCLogFileSize) {
+  if (!should_rotate(force)) {
     return;
   }
 
@@ -685,6 +685,11 @@
     jio_snprintf(time_msg, sizeof(time_msg), "File  %s rotated at %s\n",
                  _file_name, os::local_time_string((char *)time_str, sizeof(time_str)));
     write(time_msg, strlen(time_msg));
+
+    if (out != NULL) {
+      out->print(time_msg);
+    }
+
     dump_loggc_header();
     return;
   }
@@ -706,12 +711,18 @@
                  _file_name, _cur_file_num);
     jio_snprintf(current_file_name, filename_len + EXTRACHARLEN, "%s.%d" CURRENTAPPX,
                  _file_name, _cur_file_num);
-    jio_snprintf(time_msg, sizeof(time_msg), "%s GC log file has reached the"
-                           " maximum size. Saved as %s\n",
-                           os::local_time_string((char *)time_str, sizeof(time_str)),
-                           renamed_file_name);
+
+    const char* msg = force ? "GC log rotation request has been received."
+                            : "GC log file has reached the maximum size.";
+    jio_snprintf(time_msg, sizeof(time_msg), "%s %s Saved as %s\n",
+                     os::local_time_string((char *)time_str, sizeof(time_str)),
+                                                         msg, renamed_file_name);
     write(time_msg, strlen(time_msg));
 
+    if (out != NULL) {
+      out->print(time_msg);
+    }
+
     fclose(_file);
     _file = NULL;
 
@@ -752,6 +763,11 @@
                            os::local_time_string((char *)time_str, sizeof(time_str)),
                            current_file_name);
     write(time_msg, strlen(time_msg));
+
+    if (out != NULL) {
+      out->print(time_msg);
+    }
+
     dump_loggc_header();
     // remove the existing file
     if (access(current_file_name, F_OK) == 0) {
--- a/hotspot/src/share/vm/utilities/ostream.hpp	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/src/share/vm/utilities/ostream.hpp	Sun Mar 30 03:29:48 2014 -0700
@@ -115,7 +115,7 @@
    // flushing
    virtual void flush() {}
    virtual void write(const char* str, size_t len) = 0;
-   virtual void rotate_log() {} // GC log rotation
+   virtual void rotate_log(bool force, outputStream* out = NULL) {} // GC log rotation
    virtual ~outputStream() {}   // close properly on deletion
 
    void dec_cr() { dec(); cr(); }
@@ -240,8 +240,14 @@
   gcLogFileStream(const char* file_name);
   ~gcLogFileStream();
   virtual void write(const char* c, size_t len);
-  virtual void rotate_log();
+  virtual void rotate_log(bool force, outputStream* out = NULL);
   void dump_loggc_header();
+
+  /* If "force" sets true, force log file rotation from outside JVM */
+  bool should_rotate(bool force) {
+    return force ||
+             ((GCLogFileSize != 0) && ((uintx)_bytes_written >= GCLogFileSize));
+  }
 };
 
 #ifndef PRODUCT
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/gc/TestGCLogRotationViaJcmd.java	Sun Mar 30 03:29:48 2014 -0700
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test TestGCLogRotationViaJcmd.java
+ * @bug 7090324
+ * @summary test for gc log rotation via jcmd
+ * @library /testlibrary
+ * @run main/othervm -Xloggc:test.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=3 TestGCLogRotationViaJcmd
+ *
+ */
+import com.oracle.java.testlibrary.*;
+import java.io.File;
+import java.io.FilenameFilter;
+
+public class TestGCLogRotationViaJcmd {
+
+    static final File currentDirectory = new File(".");
+    static final String LOG_FILE_NAME = "test.log";
+    static final int NUM_LOGS = 3;
+
+    static FilenameFilter logFilter = new FilenameFilter() {
+        @Override
+        public boolean accept(File dir, String name) {
+            return name.startsWith(LOG_FILE_NAME);
+        }
+    };
+
+    public static void main(String[] args) throws Exception {
+        // Grab the pid from the current java process
+        String pid = Integer.toString(ProcessTools.getProcessId());
+
+        // Create a JDKToolLauncher
+        JDKToolLauncher jcmd = JDKToolLauncher.create("jcmd")
+                                              .addToolArg(pid)
+                                              .addToolArg("GC.rotate_log");
+
+        for (int times = 1; times < NUM_LOGS; times++) {
+            // Run jcmd <pid> GC.rotate_log
+            ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand());
+
+            // Make sure we didn't crash
+            OutputAnalyzer output = new OutputAnalyzer(pb.start());
+            output.shouldHaveExitValue(0);
+        }
+
+        // GC log check
+        File[] logs = currentDirectory.listFiles(logFilter);
+        if (logs.length != NUM_LOGS) {
+            throw new Error("There are only " + logs.length
+                                              + " logs instead " + NUM_LOGS);
+        }
+
+    }
+
+}
+
--- a/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/test/runtime/NMT/JcmdWithNMTDisabled.java	Sun Mar 30 03:29:48 2014 -0700
@@ -26,10 +26,7 @@
  * @key nmt jcmd
  * @summary Verify that jcmd correctly reports that NMT is not enabled
  * @library /testlibrary
- * First run without enabling NMT
- * @run main/othervm JcmdWithNMTDisabled
- * Then run with explicitly disabling NMT, should not be any difference
- * @run main/othervm -XX:NativeMemoryTracking=off JcmdWithNMTDisabled
+ * @run main JcmdWithNMTDisabled 1
  */
 
 import com.oracle.java.testlibrary.*;
@@ -39,6 +36,27 @@
   static String pid;
 
   public static void main(String args[]) throws Exception {
+
+    // This test explicitly needs to be run with the exact command lines below, not passing on
+    // arguments from the parent VM is a conscious choice to avoid NMT being turned on.
+    if (args.length > 0) {
+      ProcessBuilder pb;
+      OutputAnalyzer output;
+      String testjdkPath = System.getProperty("test.jdk");
+
+      // First run without enabling NMT
+      pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "JcmdWithNMTDisabled");
+      output = new OutputAnalyzer(pb.start());
+      output.shouldHaveExitValue(0);
+
+      // Then run with explicitly disabling NMT, should not be any difference
+      pb = ProcessTools.createJavaProcessBuilder("-Dtest.jdk=" + testjdkPath, "-XX:NativeMemoryTracking=off", "JcmdWithNMTDisabled");
+      output = new OutputAnalyzer(pb.start());
+      output.shouldHaveExitValue(0);
+
+      return;
+    }
+
     // Grab my own PID
     pid = Integer.toString(ProcessTools.getProcessId());
 
--- a/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java	Fri Mar 28 09:15:41 2014 -0700
+++ b/hotspot/test/runtime/SharedArchiveFile/CdsWriteError.java	Sun Mar 30 03:29:48 2014 -0700
@@ -22,7 +22,6 @@
  */
 
 /*
- * @ignore 8032222
  * @test CdsWriteError
  * @summary Test how VM handles situation when it is impossible to write the
  *          CDS archive. VM is expected to exit gracefully and display the
@@ -46,6 +45,12 @@
             return;
         }
 
+        // This test has been unstable for Mac OSx (see JDK-8032222)
+        if (Platform.isOSX()) {
+            System.out.println("This test is skipped on Mac");
+            return;
+        }
+
         String folderName = "tmp";
         String fileName = folderName + File.separator + "empty.jsa";
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jvmti/8036666/GetObjectLockCount.java	Sun Mar 30 03:29:48 2014 -0700
@@ -0,0 +1,284 @@
+/*
+ * Copyright 2014 SAP AG.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.jdi.AbsentInformationException;
+import com.sun.jdi.Bootstrap;
+import com.sun.jdi.LocalVariable;
+import com.sun.jdi.Location;
+import com.sun.jdi.ObjectReference;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.StackFrame;
+import com.sun.jdi.ThreadReference;
+import com.sun.jdi.Value;
+import com.sun.jdi.VirtualMachine;
+import com.sun.jdi.connect.Connector;
+import com.sun.jdi.connect.Connector.Argument;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+import com.sun.jdi.connect.LaunchingConnector;
+import com.sun.jdi.connect.VMStartException;
+import com.sun.jdi.event.BreakpointEvent;
+import com.sun.jdi.event.ClassPrepareEvent;
+import com.sun.jdi.event.Event;
+import com.sun.jdi.event.EventQueue;
+import com.sun.jdi.event.EventSet;
+import com.sun.jdi.event.VMDeathEvent;
+import com.sun.jdi.event.VMDisconnectEvent;
+import com.sun.jdi.event.VMStartEvent;
+import com.sun.jdi.request.BreakpointRequest;
+import com.sun.jdi.request.ClassPrepareRequest;
+import com.sun.jdi.request.EventRequestManager;
+
+
+/*
+ * @test GetObjectLockCount.java
+ * @bug 8036666
+ * @key regression
+ * @summary verify jvm returns correct lock recursion count
+ * @run compile -g RecursiveObjectLock.java
+ * @run main/othervm GetObjectLockCount
+ * @author axel.siebenborn@sap.com
+ */
+
+public class GetObjectLockCount {
+
+    public static final String CLASS_NAME  = "RecursiveObjectLock";
+    public static final String METHOD_NAME = "breakpoint1";
+    public static final String ARGUMENTS = "";
+
+
+    /**
+     * Find a com.sun.jdi.CommandLineLaunch connector
+     */
+    static LaunchingConnector findLaunchingConnector() {
+        List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();
+        Iterator <Connector> iter = connectors.iterator();
+        while (iter.hasNext()) {
+            Connector connector = iter.next();
+            if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
+                return (LaunchingConnector)connector;
+            }
+        }
+        throw new Error("No launching connector");
+    }
+
+    static VirtualMachine launchTarget(String mainArgs) {
+        LaunchingConnector connector = findLaunchingConnector();
+        Map<String, Argument>  arguments = connectorArguments(connector, mainArgs);
+        try {
+            return (VirtualMachine) connector.launch(arguments);
+        } catch (IOException exc) {
+            throw new Error("Unable to launch target VM: " + exc);
+        } catch (IllegalConnectorArgumentsException exc) {
+            throw new Error("Internal error: " + exc);
+        } catch (VMStartException exc) {
+            throw new Error("Target VM failed to initialize: " +
+                    exc.getMessage());
+        }
+    }
+    /**
+     * Return the launching connector's arguments.
+     */
+    static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {
+        Map<String,Connector.Argument> arguments = connector.defaultArguments();
+
+        Connector.Argument mainArg = (Connector.Argument)arguments.get("main");
+        if (mainArg == null) {
+            throw new Error("Bad launching connector");
+        }
+        mainArg.setValue(mainArgs);
+
+        Connector.Argument optionsArg = (Connector.Argument)arguments.get("options");
+        if (optionsArg == null) {
+            throw new Error("Bad launching connector");
+        }
+        optionsArg.setValue(ARGUMENTS);
+        return arguments;
+    }
+
+    private static void addClassWatch(VirtualMachine vm) {
+        EventRequestManager erm = vm.eventRequestManager();
+        ClassPrepareRequest classPrepareRequest = erm
+                .createClassPrepareRequest();
+        classPrepareRequest.addClassFilter(CLASS_NAME);
+        classPrepareRequest.setEnabled(true);
+    }
+
+    private static void addBreakpoint(VirtualMachine vm, ReferenceType refType) {
+        Location breakpointLocation = null;
+        List<Location> locs;
+        try {
+            locs = refType.allLineLocations();
+            for (Location loc: locs) {
+                if (loc.method().name().equals(METHOD_NAME)) {
+                    breakpointLocation = loc;
+                    break;
+                }
+            }
+        } catch (AbsentInformationException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        if (breakpointLocation != null) {
+            EventRequestManager evtReqMgr = vm.eventRequestManager();
+            BreakpointRequest bReq = evtReqMgr.createBreakpointRequest(breakpointLocation);
+            bReq.setSuspendPolicy(BreakpointRequest.SUSPEND_ALL);
+            bReq.enable();
+        }
+    }
+
+    /**
+     * @param args
+     * @throws InterruptedException
+     */
+    public static void main(String[] args) throws InterruptedException  {
+
+        VirtualMachine vm = launchTarget(CLASS_NAME);
+
+        // process events
+        EventQueue eventQueue = vm.eventQueue();
+        // resume the vm
+        boolean launched = false;
+
+        while (!launched) {
+            EventSet eventSet = eventQueue.remove();
+            for (Event event : eventSet) {
+                if (event instanceof VMStartEvent) {
+                    System.out.println("Vm launched");
+                    // set watch field on already loaded classes
+                    List<ReferenceType> referenceTypes = vm.classesByName(CLASS_NAME);
+                    for (ReferenceType refType : referenceTypes) {
+                        System.out.println("Found Class");
+                        addBreakpoint(vm, refType);
+                    }
+
+                    // watch for loaded classes
+                    addClassWatch(vm);
+                    vm.resume();
+                    launched = true;
+                }
+            }
+        }
+
+        Process process = vm.process();
+
+        // Copy target's output and error to our output and error.
+        Thread outThread = new StreamRedirectThread("out reader", process.getInputStream());
+        Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream());
+
+        int recursionCount = -1;
+
+        errThread.start();
+        outThread.start();
+        boolean connected = true;
+        while (connected) {
+            EventSet eventSet = eventQueue.remove();
+            for (Event event : eventSet) {
+                if (event instanceof VMDeathEvent || event instanceof VMDisconnectEvent) {
+                    // exit
+                    connected = false;
+                }
+                else if (event instanceof ClassPrepareEvent) {
+                    // watch field on loaded class
+                    System.out.println("ClassPrepareEvent");
+                    ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event;
+                    ReferenceType refType = classPrepEvent.referenceType();
+                    addBreakpoint(vm, refType);
+                } else if (event instanceof BreakpointEvent) {
+                    recursionCount = getLockRecursions(vm);
+                    System.out.println("resume...");
+                }
+            }
+            eventSet.resume();
+        }
+        // Shutdown begins when event thread terminates
+        try {
+            errThread.join(); // Make sure output is forwarded
+            outThread.join();
+        } catch (InterruptedException e) {
+            // we don't interrupt
+            e.printStackTrace();
+        }
+        if (recursionCount != 3) {
+            throw new AssertionError("recursions: expected 3, but was " + recursionCount);
+        }
+    }
+
+    public static int getLockRecursions(VirtualMachine vm) {
+        List <ThreadReference> threads = vm.allThreads();
+        for (ThreadReference thread : threads) {
+            if (thread.name().equals("main")) {
+
+                System.out.println("Found main thread.");
+                try{
+                    StackFrame frame = thread.frame(3);
+                    return frame.thisObject().entryCount();
+                } catch (Exception e) {
+                    e.printStackTrace();
+                }
+            }
+            System.out.println("Main thread not found!");
+        }
+        return -1;
+    }
+}
+
+class StreamRedirectThread extends Thread {
+
+    private final BufferedReader in;
+
+    private static final int BUFFER_SIZE = 2048;
+
+    /**
+     * Set up for copy.
+     * @param name  Name of the thread
+     * @param in    Stream to copy from
+     */
+    StreamRedirectThread(String name, InputStream in) {
+        super(name);
+        this.in = new BufferedReader(new InputStreamReader(in));
+    }
+
+    /**
+     * Copy.
+     */
+    public void run() {
+        try {
+            String line;
+            while ((line = in.readLine ()) != null) {
+                System.out.println("testvm: " + line);
+            }
+            System.out.flush();
+        } catch(IOException exc) {
+            System.err.println("Child I/O Transfer - " + exc);
+            exc.printStackTrace();
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/hotspot/test/serviceability/jvmti/8036666/RecursiveObjectLock.java	Sun Mar 30 03:29:48 2014 -0700
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2014 SAP AG.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+public class RecursiveObjectLock {
+
+    public void testMethod() {
+        synchronized (this) {
+            nestedLock1();
+        }
+    }
+
+    public void nestedLock1() {
+        synchronized (this) {
+            nestedLock2();
+        }
+    }
+
+    public void nestedLock2() {
+        synchronized (this) {
+            callWait();
+        }
+    }
+
+    public void callWait(){
+        try {
+            this.wait(1);
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+        }
+        breakpoint1();
+    }
+
+    public static void breakpoint1() {
+        // purpose: hold a breakpoint
+    }
+
+    public static void main(String[] args) {
+        RecursiveObjectLock ro = new RecursiveObjectLock();
+        ro.testMethod();
+        System.out.println("ready");
+    }
+
+}