src/share/vm/services/classLoadingService.cpp

Wed, 02 Aug 2017 10:21:43 +0800

author
aoqi
date
Wed, 02 Aug 2017 10:21:43 +0800
changeset 423
6cfa41b33dfb
parent 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

#5933 Backport of JDK-8047382: hotspot build failed with gcc version Red Hat 4.4.6-4.
Summary: Removed the Solaris specific conditionalization for casting to void * within calls to HS_DTRACE_PROBE* to enable successful compilation with gcc Red Hat 4.4.6-4.
Contributed-by: lfoltan
Reviewed-by: hseigel, stefank

aoqi@0 1 /*
aoqi@423 2 * Copyright (c) 2003, 2015, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation.
aoqi@0 8 *
aoqi@0 9 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 12 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 13 * accompanied this code).
aoqi@0 14 *
aoqi@0 15 * You should have received a copy of the GNU General Public License version
aoqi@0 16 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 18 *
aoqi@0 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 20 * or visit www.oracle.com if you need additional information or have any
aoqi@0 21 * questions.
aoqi@0 22 *
aoqi@0 23 */
aoqi@0 24
aoqi@0 25 #include "precompiled.hpp"
aoqi@0 26 #include "classfile/systemDictionary.hpp"
aoqi@0 27 #include "memory/allocation.hpp"
aoqi@0 28 #include "memory/universe.hpp"
aoqi@0 29 #include "oops/oop.inline.hpp"
aoqi@0 30 #include "runtime/mutexLocker.hpp"
aoqi@0 31 #include "services/classLoadingService.hpp"
aoqi@0 32 #include "services/memoryService.hpp"
aoqi@0 33 #include "utilities/dtrace.hpp"
aoqi@0 34 #include "utilities/macros.hpp"
aoqi@0 35
aoqi@0 36 #ifdef DTRACE_ENABLED
aoqi@0 37
aoqi@0 38 // Only bother with this argument setup if dtrace is available
aoqi@0 39
aoqi@0 40 #ifndef USDT2
aoqi@0 41
aoqi@0 42 HS_DTRACE_PROBE_DECL4(hotspot, class__loaded, char*, int, oop, bool);
aoqi@0 43 HS_DTRACE_PROBE_DECL4(hotspot, class__unloaded, char*, int, oop, bool);
aoqi@0 44
aoqi@0 45 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared) \
aoqi@0 46 { \
aoqi@0 47 char* data = NULL; \
aoqi@0 48 int len = 0; \
aoqi@0 49 Symbol* name = (clss)->name(); \
aoqi@0 50 if (name != NULL) { \
aoqi@0 51 data = (char*)name->bytes(); \
aoqi@0 52 len = name->utf8_length(); \
aoqi@0 53 } \
aoqi@0 54 HS_DTRACE_PROBE4(hotspot, class__##type, \
aoqi@423 55 data, len, (void *)(clss)->class_loader(), (shared)); \
aoqi@0 56 }
aoqi@0 57
aoqi@0 58 #else /* USDT2 */
aoqi@0 59
aoqi@0 60 #define HOTSPOT_CLASS_unloaded HOTSPOT_CLASS_UNLOADED
aoqi@0 61 #define HOTSPOT_CLASS_loaded HOTSPOT_CLASS_LOADED
aoqi@0 62 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared) \
aoqi@0 63 { \
aoqi@0 64 char* data = NULL; \
aoqi@0 65 int len = 0; \
aoqi@0 66 Symbol* name = (clss)->name(); \
aoqi@0 67 if (name != NULL) { \
aoqi@0 68 data = (char*)name->bytes(); \
aoqi@0 69 len = name->utf8_length(); \
aoqi@0 70 } \
aoqi@0 71 HOTSPOT_CLASS_##type( /* type = unloaded, loaded */ \
aoqi@0 72 data, len, (clss)->class_loader(), (shared)); \
aoqi@0 73 }
aoqi@0 74
aoqi@0 75 #endif /* USDT2 */
aoqi@0 76 #else // ndef DTRACE_ENABLED
aoqi@0 77
aoqi@0 78 #define DTRACE_CLASSLOAD_PROBE(type, clss, shared)
aoqi@0 79
aoqi@0 80 #endif
aoqi@0 81
aoqi@0 82 #if INCLUDE_MANAGEMENT
aoqi@0 83 // counters for classes loaded from class files
aoqi@0 84 PerfCounter* ClassLoadingService::_classes_loaded_count = NULL;
aoqi@0 85 PerfCounter* ClassLoadingService::_classes_unloaded_count = NULL;
aoqi@0 86 PerfCounter* ClassLoadingService::_classbytes_loaded = NULL;
aoqi@0 87 PerfCounter* ClassLoadingService::_classbytes_unloaded = NULL;
aoqi@0 88
aoqi@0 89 // counters for classes loaded from shared archive
aoqi@0 90 PerfCounter* ClassLoadingService::_shared_classes_loaded_count = NULL;
aoqi@0 91 PerfCounter* ClassLoadingService::_shared_classes_unloaded_count = NULL;
aoqi@0 92 PerfCounter* ClassLoadingService::_shared_classbytes_loaded = NULL;
aoqi@0 93 PerfCounter* ClassLoadingService::_shared_classbytes_unloaded = NULL;
aoqi@0 94 PerfVariable* ClassLoadingService::_class_methods_size = NULL;
aoqi@0 95
aoqi@0 96 void ClassLoadingService::init() {
aoqi@0 97 EXCEPTION_MARK;
aoqi@0 98
aoqi@0 99 // These counters are for java.lang.management API support.
aoqi@0 100 // They are created even if -XX:-UsePerfData is set and in
aoqi@0 101 // that case, they will be allocated on C heap.
aoqi@0 102 _classes_loaded_count =
aoqi@0 103 PerfDataManager::create_counter(JAVA_CLS, "loadedClasses",
aoqi@0 104 PerfData::U_Events, CHECK);
aoqi@0 105
aoqi@0 106 _classes_unloaded_count =
aoqi@0 107 PerfDataManager::create_counter(JAVA_CLS, "unloadedClasses",
aoqi@0 108 PerfData::U_Events, CHECK);
aoqi@0 109
aoqi@0 110 _shared_classes_loaded_count =
aoqi@0 111 PerfDataManager::create_counter(JAVA_CLS, "sharedLoadedClasses",
aoqi@0 112 PerfData::U_Events, CHECK);
aoqi@0 113
aoqi@0 114 _shared_classes_unloaded_count =
aoqi@0 115 PerfDataManager::create_counter(JAVA_CLS, "sharedUnloadedClasses",
aoqi@0 116 PerfData::U_Events, CHECK);
aoqi@0 117
aoqi@0 118 if (UsePerfData) {
aoqi@0 119 _classbytes_loaded =
aoqi@0 120 PerfDataManager::create_counter(SUN_CLS, "loadedBytes",
aoqi@0 121 PerfData::U_Bytes, CHECK);
aoqi@0 122
aoqi@0 123 _classbytes_unloaded =
aoqi@0 124 PerfDataManager::create_counter(SUN_CLS, "unloadedBytes",
aoqi@0 125 PerfData::U_Bytes, CHECK);
aoqi@0 126 _shared_classbytes_loaded =
aoqi@0 127 PerfDataManager::create_counter(SUN_CLS, "sharedLoadedBytes",
aoqi@0 128 PerfData::U_Bytes, CHECK);
aoqi@0 129
aoqi@0 130 _shared_classbytes_unloaded =
aoqi@0 131 PerfDataManager::create_counter(SUN_CLS, "sharedUnloadedBytes",
aoqi@0 132 PerfData::U_Bytes, CHECK);
aoqi@0 133 _class_methods_size =
aoqi@0 134 PerfDataManager::create_variable(SUN_CLS, "methodBytes",
aoqi@0 135 PerfData::U_Bytes, CHECK);
aoqi@0 136 }
aoqi@0 137 }
aoqi@0 138
aoqi@0 139 void ClassLoadingService::notify_class_unloaded(InstanceKlass* k) {
aoqi@0 140 DTRACE_CLASSLOAD_PROBE(unloaded, k, false);
aoqi@0 141 // Classes that can be unloaded must be non-shared
aoqi@0 142 _classes_unloaded_count->inc();
aoqi@0 143
aoqi@0 144 if (UsePerfData) {
aoqi@0 145 // add the class size
aoqi@0 146 size_t size = compute_class_size(k);
aoqi@0 147 _classbytes_unloaded->inc(size);
aoqi@0 148
aoqi@0 149 // Compute method size & subtract from running total.
aoqi@0 150 // We are called during phase 1 of mark sweep, so it's
aoqi@0 151 // still ok to iterate through Method*s here.
aoqi@0 152 Array<Method*>* methods = k->methods();
aoqi@0 153 for (int i = 0; i < methods->length(); i++) {
aoqi@0 154 _class_methods_size->inc(-methods->at(i)->size());
aoqi@0 155 }
aoqi@0 156 }
aoqi@0 157
aoqi@0 158 if (TraceClassUnloading) {
aoqi@0 159 ResourceMark rm;
aoqi@0 160 tty->print_cr("[Unloading class %s " INTPTR_FORMAT "]", k->external_name(), p2i(k));
aoqi@0 161 }
aoqi@0 162 }
aoqi@0 163
aoqi@0 164 void ClassLoadingService::notify_class_loaded(InstanceKlass* k, bool shared_class) {
aoqi@0 165 DTRACE_CLASSLOAD_PROBE(loaded, k, shared_class);
aoqi@0 166 PerfCounter* classes_counter = (shared_class ? _shared_classes_loaded_count
aoqi@0 167 : _classes_loaded_count);
aoqi@0 168 // increment the count
aoqi@0 169 classes_counter->inc();
aoqi@0 170
aoqi@0 171 if (UsePerfData) {
aoqi@0 172 PerfCounter* classbytes_counter = (shared_class ? _shared_classbytes_loaded
aoqi@0 173 : _classbytes_loaded);
aoqi@0 174 // add the class size
aoqi@0 175 size_t size = compute_class_size(k);
aoqi@0 176 classbytes_counter->inc(size);
aoqi@0 177 }
aoqi@0 178 }
aoqi@0 179
aoqi@0 180 size_t ClassLoadingService::compute_class_size(InstanceKlass* k) {
aoqi@0 181 // lifted from ClassStatistics.do_class(Klass* k)
aoqi@0 182
aoqi@0 183 size_t class_size = 0;
aoqi@0 184
aoqi@0 185 class_size += k->size();
aoqi@0 186
aoqi@0 187 if (k->oop_is_instance()) {
aoqi@0 188 class_size += k->methods()->size();
aoqi@0 189 // FIXME: Need to count the contents of methods
aoqi@0 190 class_size += k->constants()->size();
aoqi@0 191 class_size += k->local_interfaces()->size();
aoqi@0 192 class_size += k->transitive_interfaces()->size();
aoqi@0 193 // We do not have to count implementors, since we only store one!
aoqi@0 194 // FIXME: How should these be accounted for, now when they have moved.
aoqi@0 195 //class_size += k->fields()->size();
aoqi@0 196 }
aoqi@0 197 return class_size * oopSize;
aoqi@0 198 }
aoqi@0 199
aoqi@0 200
aoqi@0 201 bool ClassLoadingService::set_verbose(bool verbose) {
aoqi@0 202 MutexLocker m(Management_lock);
aoqi@0 203
aoqi@0 204 // verbose will be set to the previous value
aoqi@0 205 bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassLoading", &verbose, Flag::MANAGEMENT);
aoqi@0 206 assert(succeed, "Setting TraceClassLoading flag fails");
aoqi@0 207 reset_trace_class_unloading();
aoqi@0 208
aoqi@0 209 return verbose;
aoqi@0 210 }
aoqi@0 211
aoqi@0 212 // Caller to this function must own Management_lock
aoqi@0 213 void ClassLoadingService::reset_trace_class_unloading() {
aoqi@0 214 assert(Management_lock->owned_by_self(), "Must own the Management_lock");
aoqi@0 215 bool value = MemoryService::get_verbose() || ClassLoadingService::get_verbose();
aoqi@0 216 bool succeed = CommandLineFlags::boolAtPut((char*)"TraceClassUnloading", &value, Flag::MANAGEMENT);
aoqi@0 217 assert(succeed, "Setting TraceClassUnLoading flag fails");
aoqi@0 218 }
aoqi@0 219
aoqi@0 220 GrowableArray<KlassHandle>* LoadedClassesEnumerator::_loaded_classes = NULL;
aoqi@0 221 Thread* LoadedClassesEnumerator::_current_thread = NULL;
aoqi@0 222
aoqi@0 223 LoadedClassesEnumerator::LoadedClassesEnumerator(Thread* cur_thread) {
aoqi@0 224 assert(cur_thread == Thread::current(), "Check current thread");
aoqi@0 225
aoqi@0 226 int init_size = ClassLoadingService::loaded_class_count();
aoqi@0 227 _klass_handle_array = new GrowableArray<KlassHandle>(init_size);
aoqi@0 228
aoqi@0 229 // For consistency of the loaded classes, grab the SystemDictionary lock
aoqi@0 230 MutexLocker sd_mutex(SystemDictionary_lock);
aoqi@0 231
aoqi@0 232 // Set _loaded_classes and _current_thread and begin enumerating all classes.
aoqi@0 233 // Only one thread will do the enumeration at a time.
aoqi@0 234 // These static variables are needed and they are used by the static method
aoqi@0 235 // add_loaded_class called from classes_do().
aoqi@0 236 _loaded_classes = _klass_handle_array;
aoqi@0 237 _current_thread = cur_thread;
aoqi@0 238
aoqi@0 239 SystemDictionary::classes_do(&add_loaded_class);
aoqi@0 240
aoqi@0 241 // FIXME: Exclude array klasses for now
aoqi@0 242 // Universe::basic_type_classes_do(&add_loaded_class);
aoqi@0 243 }
aoqi@0 244
aoqi@0 245 #endif // INCLUDE_MANAGEMENT

mercurial