8148195: Some InstanceKlass and MethodCounters fields can be excluded when JVMTI is not supported
authorcjplummer
Thu, 21 Apr 2016 20:49:11 -0700
changeset 38059 86ab3f0a9f87
parent 38058 17294a77a970
child 38060 954c9575f653
child 38061 5fe046aef3b9
8148195: Some InstanceKlass and MethodCounters fields can be excluded when JVMTI is not supported Summary: Removed "previous version", "cached class file", and breakpoint related fields and code when JVMTI is not supported Reviewed-by: coleenp, sspitsyn
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java
hotspot/src/share/vm/ci/ciMethod.cpp
hotspot/src/share/vm/oops/instanceKlass.cpp
hotspot/src/share/vm/oops/instanceKlass.hpp
hotspot/src/share/vm/oops/method.cpp
hotspot/src/share/vm/oops/method.hpp
hotspot/src/share/vm/oops/methodCounters.hpp
hotspot/src/share/vm/runtime/vmStructs.cpp
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/BreakpointInfo.java	Thu Apr 21 20:49:11 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2016 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
@@ -46,6 +46,11 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+    if (!VM.getVM().isJvmtiSupported()) {
+      // no BreakpointInfo support without JVMTI
+      return;
+    }
+
     Type type                  = db.lookupType("BreakpointInfo");
 
     origBytecodeField   = type.getCIntegerField("_orig_bytecode");
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java	Thu Apr 21 20:49:11 2016 -0700
@@ -85,7 +85,9 @@
     isMarkedDependent    = new CIntField(type.getCIntegerField("_is_marked_dependent"), 0);
     initState            = new CIntField(type.getCIntegerField("_init_state"), 0);
     itableLen            = new CIntField(type.getCIntegerField("_itable_len"), 0);
-    breakpoints          = type.getAddressField("_breakpoints");
+    if (VM.getVM().isJvmtiSupported()) {
+      breakpoints        = type.getAddressField("_breakpoints");
+    }
     genericSignatureIndex = new CIntField(type.getCIntegerField("_generic_signature_index"), 0);
     majorVersion         = new CIntField(type.getCIntegerField("_major_version"), 0);
     minorVersion         = new CIntField(type.getCIntegerField("_minor_version"), 0);
@@ -837,6 +839,9 @@
 
   /** Breakpoint support (see methods on Method* for details) */
   public BreakpointInfo getBreakpoints() {
+    if (!VM.getVM().isJvmtiSupported()) {
+      return null;
+    }
     Address addr = getAddress().getAddressAt(breakpoints.getOffset());
     return (BreakpointInfo) VMObjectFactory.newObject(BreakpointInfo.class, addr);
   }
--- a/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VM.java	Thu Apr 21 20:49:11 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2016, 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
@@ -87,6 +87,8 @@
   private StubRoutines stubRoutines;
   private Bytes        bytes;
 
+  /** Flag indicating if JVMTI support is included in the build */
+  private boolean      isJvmtiSupported;
   /** Flags indicating whether we are attached to a core, C1, or C2 build */
   private boolean      usingClientCompiler;
   private boolean      usingServerCompiler;
@@ -336,6 +338,16 @@
     stackBias    = db.lookupIntConstant("STACK_BIAS").intValue();
     invocationEntryBCI = db.lookupIntConstant("InvocationEntryBci").intValue();
 
+    // We infer the presence of JVMTI from the presence of the InstanceKlass::_breakpoints field.
+    {
+      Type type = db.lookupType("InstanceKlass");
+      if (type.getField("_breakpoints", false, false) == null) {
+        isJvmtiSupported = false;
+      } else {
+        isJvmtiSupported = true;
+      }
+    }
+
     // We infer the presence of C1 or C2 from a couple of fields we
     // already have present in the type database
     {
@@ -701,6 +713,11 @@
     return isBigEndian;
   }
 
+  /** Returns true if JVMTI is supported, false otherwise */
+  public boolean isJvmtiSupported() {
+    return isJvmtiSupported;
+  }
+
   /** Returns true if this is a "core" build, false if either C1 or C2
       is present */
   public boolean isCore() {
--- a/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp	Thu Apr 21 20:49:11 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2016, 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
@@ -202,6 +202,7 @@
   _code = (address)arena->Amalloc(code_size());
   memcpy(_code, me->code_base(), code_size());
 
+#if INCLUDE_JVMTI
   // Revert any breakpoint bytecodes in ci's copy
   if (me->number_of_breakpoints() > 0) {
     BreakpointInfo* bp = me->method_holder()->breakpoints();
@@ -211,6 +212,7 @@
       }
     }
   }
+#endif
 
   // And load the exception table.
   ExceptionTable exc_table(me);
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp	Thu Apr 21 20:49:11 2016 -0700
@@ -2032,10 +2032,11 @@
   return (old_state != is_in_error_state());
 }
 
+#if INCLUDE_JVMTI
 static void clear_all_breakpoints(Method* m) {
   m->clear_all_breakpoints();
 }
-
+#endif
 
 void InstanceKlass::notify_unload_class(InstanceKlass* ik) {
   // notify the debugger
@@ -2097,6 +2098,7 @@
   // DC::remove_all_dependents() when it touches unloaded nmethod.
   dependencies().wipe();
 
+#if INCLUDE_JVMTI
   // Deallocate breakpoint records
   if (breakpoints() != 0x0) {
     methods_do(clear_all_breakpoints);
@@ -2108,6 +2110,7 @@
     os::free(_cached_class_file);
     _cached_class_file = NULL;
   }
+#endif
 
   // Decrement symbol reference counts associated with the unloaded class.
   if (_name != NULL) _name->decrement_refcount();
@@ -2841,7 +2844,7 @@
   {
     bool have_pv = false;
     // previous versions are linked together through the InstanceKlass
-    for (InstanceKlass* pv_node = _previous_versions;
+    for (InstanceKlass* pv_node = previous_versions();
          pv_node != NULL;
          pv_node = pv_node->previous_versions()) {
       if (!have_pv)
@@ -3334,7 +3337,7 @@
 }
 #endif
 
-
+#if INCLUDE_JVMTI
 
 // RedefineClasses() support for previous versions:
 int InstanceKlass::_previous_version_count = 0;
@@ -3549,6 +3552,7 @@
   _previous_version_count++;
 } // end add_previous_version()
 
+#endif // INCLUDE_JVMTI
 
 Method* InstanceKlass::method_with_idnum(int idnum) {
   Method* m = NULL;
@@ -3598,7 +3602,7 @@
   return method;
 }
 
-
+#if INCLUDE_JVMTI
 jint InstanceKlass::get_cached_class_file_len() {
   return VM_RedefineClasses::get_cached_class_file_len(_cached_class_file);
 }
@@ -3606,3 +3610,4 @@
 unsigned char * InstanceKlass::get_cached_class_file_bytes() {
   return VM_RedefineClasses::get_cached_class_file_bytes(_cached_class_file);
 }
+#endif
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp	Thu Apr 21 20:49:11 2016 -0700
@@ -57,7 +57,9 @@
 
 
 // forward declaration for class -- see below for definition
+#if INCLUDE_JVMTI
 class BreakpointInfo;
+#endif
 class ClassFileParser;
 class KlassDepChange;
 class DependencyContext;
@@ -230,12 +232,14 @@
   jmethodID*      _methods_jmethod_ids;  // jmethodIDs corresponding to method_idnum, or NULL if none
   intptr_t        _dep_context;          // packed DependencyContext structure
   nmethod*        _osr_nmethods_head;    // Head of list of on-stack replacement nmethods for this class
+#if INCLUDE_JVMTI
   BreakpointInfo* _breakpoints;          // bpt lists, managed by Method*
   // Linked instanceKlasses of previous versions
   InstanceKlass* _previous_versions;
   // JVMTI fields can be moved to their own structure - see 6315920
   // JVMTI: cached class file, before retransformable agent modified it in CFLH
   JvmtiCachedClassFileData* _cached_class_file;
+#endif
 
   volatile u2     _idnum_allocated_count;         // JNI/JVMTI: increments with the addition of methods, old ids don't change
 
@@ -245,7 +249,9 @@
   u1              _init_state;                    // state of class
   u1              _reference_type;                // reference type
 
+#if INCLUDE_JVMTI
   JvmtiCachedClassFieldMap* _jvmti_cached_class_field_map;  // JVMTI: used during heap iteration
+#endif
 
   NOT_PRODUCT(int _verify_count;)  // to avoid redundant verifies
 
@@ -687,10 +693,14 @@
     _nonstatic_oop_map_size = words;
   }
 
+#if INCLUDE_JVMTI
   // RedefineClasses() support for previous versions:
   void add_previous_version(instanceKlassHandle ikh, int emcp_method_count);
 
   InstanceKlass* previous_versions() const { return _previous_versions; }
+#else
+  InstanceKlass* previous_versions() const { return NULL; }
+#endif
 
   InstanceKlass* get_klass_version(int version) {
     for (InstanceKlass* ik = this; ik != NULL; ik = ik->previous_versions()) {
@@ -738,6 +748,8 @@
   bool is_mirror_instance_klass() const       { return is_kind(_misc_kind_mirror); }
   bool is_class_loader_instance_klass() const { return is_kind(_misc_kind_class_loader); }
 
+#if INCLUDE_JVMTI
+
   void init_previous_versions() {
     _previous_versions = NULL;
   }
@@ -764,6 +776,16 @@
     return _jvmti_cached_class_field_map;
   }
 
+#else // INCLUDE_JVMTI
+
+  static void purge_previous_versions(InstanceKlass* ik) { return; };
+  static bool has_previous_versions() { return false; }
+
+  void set_cached_class_file(JvmtiCachedClassFileData *data) { ShouldNotReachHere(); }
+  JvmtiCachedClassFileData * get_cached_class_file() { return (JvmtiCachedClassFileData *)NULL; }
+
+#endif // INCLUDE_JVMTI
+
   bool has_default_methods() const {
     return (_misc_flags & _misc_has_default_methods) != 0;
   }
@@ -882,9 +904,11 @@
   int mark_osr_nmethods(const Method* m);
   nmethod* lookup_osr_nmethod(const Method* m, int bci, int level, bool match_level) const;
 
+#if INCLUDE_JVMTI
   // Breakpoint support (see methods on Method* for details)
   BreakpointInfo* breakpoints() const       { return _breakpoints; };
   void set_breakpoints(BreakpointInfo* bps) { _breakpoints = bps; };
+#endif
 
   // support for stub routines
   static ByteSize init_state_offset()  { return in_ByteSize(offset_of(InstanceKlass, _init_state)); }
@@ -1253,9 +1277,11 @@
   // Free CHeap allocated fields.
   void release_C_heap_structures();
 
+#if INCLUDE_JVMTI
   // RedefineClasses support
   void link_previous_versions(InstanceKlass* pv) { _previous_versions = pv; }
   void mark_newly_obsolete_methods(Array<Method*>* old_methods, int emcp_method_count);
+#endif
 public:
   // CDS support - remove and restore oops from metadata. Oops are not shared.
   virtual void remove_unshareable_info();
--- a/hotspot/src/share/vm/oops/method.cpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/oops/method.cpp	Thu Apr 21 20:49:11 2016 -0700
@@ -1639,6 +1639,7 @@
   return true;
 }
 
+#if INCLUDE_JVMTI
 
 Bytecodes::Code Method::orig_bytecode_at(int bci) const {
   BreakpointInfo* bp = method_holder()->breakpoints();
@@ -1719,6 +1720,7 @@
   clear_matches(this, -1);
 }
 
+#endif // INCLUDE_JVMTI
 
 int Method::invocation_count() {
   MethodCounters *mcs = method_counters();
@@ -1784,6 +1786,8 @@
   }
 }
 
+#if INCLUDE_JVMTI
+
 BreakpointInfo::BreakpointInfo(Method* m, int bci) {
   _bci = bci;
   _name_index = m->name_index();
@@ -1821,6 +1825,8 @@
   method->decr_number_of_breakpoints(Thread::current());
 }
 
+#endif // INCLUDE_JVMTI
+
 // jmethodID handling
 
 // This is a block allocating object, sort of like JNIHandleBlock, only a
--- a/hotspot/src/share/vm/oops/method.hpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/oops/method.hpp	Thu Apr 21 20:49:11 2016 -0700
@@ -195,8 +195,18 @@
   }
 
   // JVMTI breakpoints
+#if !INCLUDE_JVMTI
+  Bytecodes::Code orig_bytecode_at(int bci) const {
+    ShouldNotReachHere();
+    return Bytecodes::_shouldnotreachhere;
+  }
+  void set_orig_bytecode_at(int bci, Bytecodes::Code code) {
+    ShouldNotReachHere();
+  };
+  u2   number_of_breakpoints() const {return 0;}
+#else // !INCLUDE_JVMTI
   Bytecodes::Code orig_bytecode_at(int bci) const;
-  void        set_orig_bytecode_at(int bci, Bytecodes::Code code);
+  void set_orig_bytecode_at(int bci, Bytecodes::Code code);
   void set_breakpoint(int bci);
   void clear_breakpoint(int bci);
   void clear_all_breakpoints();
@@ -229,6 +239,7 @@
       mcs->clear_number_of_breakpoints();
     }
   }
+#endif // !INCLUDE_JVMTI
 
   // index into InstanceKlass methods() array
   // note: also used by jfr
@@ -1046,6 +1057,8 @@
 };
 
 
+#if INCLUDE_JVMTI
+
 /// Fast Breakpoints.
 
 // If this structure gets more complicated (because bpts get numerous),
@@ -1090,6 +1103,8 @@
   void clear(Method* method);
 };
 
+#endif // INCLUDE_JVMTI
+
 // Utility class for access exception handlers
 class ExceptionTable : public StackObj {
  private:
--- a/hotspot/src/share/vm/oops/methodCounters.hpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/oops/methodCounters.hpp	Thu Apr 21 20:49:11 2016 -0700
@@ -38,7 +38,9 @@
   int               _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
 #endif
+#if INCLUDE_JVMTI
   u2                _number_of_breakpoints;      // fullspeed debugging support
+#endif
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
   InvocationCounter _backedge_counter;           // Incremented before each backedge taken - used to trigger frequencey-based optimizations
   // NMethod age is a counter for warm methods detection in the code cache sweeper.
@@ -62,8 +64,7 @@
   u1                _highest_osr_comp_level;      // Same for OSR level
 #endif
 
-  MethodCounters(methodHandle mh) : _number_of_breakpoints(0),
-                                    _nmethod_age(INT_MAX)
+  MethodCounters(methodHandle mh) : _nmethod_age(INT_MAX)
 #ifdef TIERED
                                  , _rate(0),
                                    _prev_time(0),
@@ -73,6 +74,7 @@
   {
     set_interpreter_invocation_count(0);
     set_interpreter_throwout_count(0);
+    JVMTI_ONLY(clear_number_of_breakpoints());
     invocation_counter()->init();
     backedge_counter()->init();
 
@@ -153,10 +155,12 @@
 
 #endif // defined(COMPILER2) || INCLUDE_JVMCI
 
+#if INCLUDE_JVMTI
   u2   number_of_breakpoints() const   { return _number_of_breakpoints; }
   void incr_number_of_breakpoints()    { ++_number_of_breakpoints; }
   void decr_number_of_breakpoints()    { --_number_of_breakpoints; }
   void clear_number_of_breakpoints()   { _number_of_breakpoints = 0; }
+#endif
 
 #ifdef TIERED
   jlong prev_time() const                        { return _prev_time; }
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Apr 21 20:11:40 2016 +0000
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp	Thu Apr 21 20:49:11 2016 -0700
@@ -337,7 +337,7 @@
   volatile_nonstatic_field(InstanceKlass,      _oop_map_cache,                                OopMapCache*)                          \
   nonstatic_field(InstanceKlass,               _jni_ids,                                      JNIid*)                                \
   nonstatic_field(InstanceKlass,               _osr_nmethods_head,                            nmethod*)                              \
-  nonstatic_field(InstanceKlass,               _breakpoints,                                  BreakpointInfo*)                       \
+  JVMTI_ONLY(nonstatic_field(InstanceKlass,    _breakpoints,                                  BreakpointInfo*))                      \
   nonstatic_field(InstanceKlass,               _generic_signature_index,                      u2)                                    \
   nonstatic_field(InstanceKlass,               _methods_jmethod_ids,                          jmethodID*)                            \
   volatile_nonstatic_field(InstanceKlass,      _idnum_allocated_count,                        u2)                                    \
@@ -387,7 +387,7 @@
   nonstatic_field(MethodCounters,              _backedge_mask,                                int)                                   \
   COMPILER2_OR_JVMCI_PRESENT(nonstatic_field(MethodCounters, _interpreter_invocation_count,   int))                                  \
   COMPILER2_OR_JVMCI_PRESENT(nonstatic_field(MethodCounters, _interpreter_throwout_count,     u2))                                   \
-  nonstatic_field(MethodCounters,              _number_of_breakpoints,                        u2)                                    \
+  JVMTI_ONLY(nonstatic_field(MethodCounters,   _number_of_breakpoints,                        u2))                                   \
   nonstatic_field(MethodCounters,              _invocation_counter,                           InvocationCounter)                     \
   nonstatic_field(MethodCounters,              _backedge_counter,                             InvocationCounter)                     \
   nonstatic_field(Method,                      _constMethod,                                  ConstMethod*)                          \
@@ -447,11 +447,11 @@
   nonstatic_field(ExceptionTableElement,       end_pc,                                        u2)                                    \
   nonstatic_field(ExceptionTableElement,       handler_pc,                                    u2)                                    \
   nonstatic_field(ExceptionTableElement,       catch_type_index,                              u2)                                    \
-  nonstatic_field(BreakpointInfo,              _orig_bytecode,                                Bytecodes::Code)                       \
-  nonstatic_field(BreakpointInfo,              _bci,                                          int)                                   \
-  nonstatic_field(BreakpointInfo,              _name_index,                                   u2)                                    \
-  nonstatic_field(BreakpointInfo,              _signature_index,                              u2)                                    \
-  nonstatic_field(BreakpointInfo,              _next,                                         BreakpointInfo*)                       \
+  JVMTI_ONLY(nonstatic_field(BreakpointInfo,   _orig_bytecode,                                Bytecodes::Code))                      \
+  JVMTI_ONLY(nonstatic_field(BreakpointInfo,   _bci,                                          int))                                  \
+  JVMTI_ONLY(nonstatic_field(BreakpointInfo,   _name_index,                                   u2))                                   \
+  JVMTI_ONLY(nonstatic_field(BreakpointInfo,   _signature_index,                              u2))                                   \
+  JVMTI_ONLY(nonstatic_field(BreakpointInfo,   _next,                                         BreakpointInfo*))                      \
   /***********/                                                                                                                      \
   /* JNI IDs */                                                                                                                      \
   /***********/                                                                                                                      \