1 /* 2 * Copyright (c) 2014, 2015, Dynatrace and/or its affiliates. All rights reserved. 3 * 4 * This file is part of the Lock Contention Tracing Subsystem for the HotSpot 5 * Virtual Machine, which is developed at Christian Doppler Laboratory on 6 * Monitoring and Evolution of Very-Large-Scale Software Systems. Please 7 * contact us at <http://mevss.jku.at/> if you need additional information 8 * or have any questions. 9 * 10 * This code is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 only, as 12 * published by the Free Software Foundation. 13 * 14 * This code is distributed in the hope that it will be useful, but WITHOUT 15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 17 * version 2 for more details (a copy is included in the LICENSE file that 18 * accompanied this code). 19 * 20 * You should have received a copy of the GNU General Public License version 21 * 2 along with this work. If not, see <http://www.gnu.org/licenses/>. 22 * 23 */ 24 25 #ifndef SHARE_VM_EVTRACE_TRACEMETADATA_INLINE_HPP 26 #define SHARE_VM_EVTRACE_TRACEMETADATA_INLINE_HPP 27 28 #include "runtime/thread.hpp" 29 #include "runtime/objectMonitor.hpp" 30 #include "runtime/objectMonitor.inline.hpp" 31 #include "jvmtifiles/jvmtiEnv.hpp" 32 33 inline TraceTypes::timestamp TraceMetadata::time_now() { 34 return (TraceTypes::timestamp) os::javaTimeNanos(); 35 } 36 37 inline TraceTypes::thread_id TraceMetadata::thread_id(Thread *t) { 38 assert(t != NULL, "thread is NULL"); 39 if (t->is_Java_thread()) { 40 JavaThread *jt = (JavaThread *) t; 41 return (TraceTypes::thread_id) java_lang_Thread::thread_id(jt->threadObj()); 42 } 43 return (TraceTypes::thread_id) -t->osthread()->thread_identifier(); 44 } 45 46 inline TraceTypes::object_id TraceMetadata::object_id(oop obj) { 47 assert(obj != NULL, "object is NULL"); 48 return (TraceTypes::object_id) obj->identity_hash(); 49 } 50 51 inline TraceTypes::objmonitor_id TraceMetadata::objmonitor_id(ObjectMonitor* m) { 52 assert(m != NULL, "object monitor is NULL"); 53 // NOTE: object monitors are native objects and are not moved by the garbage collector, so 54 // they can be identified by their address. However, monitors are allocated from pools and 55 // recycled after an object dies or on deflation. We must take this lifecycle into account 56 // when associating object monitors with objects. 57 return (TraceTypes::objmonitor_id) (intptr_t) m; 58 } 59 60 inline TraceTypes::object_id TraceMetadata::objmonitor_object_id(ObjectMonitor* m) { 61 assert(m != NULL, "object monitor is NULL"); 62 if (m->header()->has_no_hash()) { 63 oop obj = (oop) m->object(); 64 return (TraceTypes::object_id) obj->identity_hash(); 65 } 66 return (TraceTypes::object_id) m->header()->hash(); 67 } 68 69 inline TraceTypes::thread_state TraceMetadata::thread_state(Thread *t) { 70 assert(t != NULL, "thread is NULL"); 71 assert(t->is_Java_thread(), "only Java threads supported"); 72 73 // just use JVMTI thread states 74 JavaThread *jt = (JavaThread *) t; 75 TraceTypes::thread_state state = 0; 76 if (jt->threadObj() != NULL) { // provides most state bits 77 state = (TraceTypes::thread_state) java_lang_Thread::get_thread_status(jt->threadObj()); 78 } 79 // additional state bits 80 if (jt->is_ext_suspended() || jt->is_external_suspend()) { // same as is_being_ext_suspended() but without locking 81 state |= JVMTI_THREAD_STATE_SUSPENDED; 82 } 83 JavaThreadState jts = jt->thread_state(); 84 if (jts == _thread_in_native) { 85 state |= JVMTI_THREAD_STATE_IN_NATIVE; 86 } 87 OSThread* osThread = jt->osthread(); 88 if (osThread != NULL && osThread->interrupted()) { 89 state |= JVMTI_THREAD_STATE_INTERRUPTED; 90 } 91 return state; 92 } 93 94 inline TraceTypes::classloader_id TraceMetadata::classloader_id(ClassLoaderData* cld) { 95 return (TraceTypes::classloader_id) (intptr_t) cld; 96 } 97 98 inline TraceTypes::class_id TraceMetadata::class_id(Klass *klass, bool &added) { 99 added = false; 100 if (!klass->is_tracing_known()) { 101 added = klass->atomic_mark_tracing_known(); 102 } 103 return (TraceTypes::class_id) (intptr_t) klass; 104 } 105 106 inline TraceTypes::method_id TraceMetadata::method_id(Method* method, bool& added) { 107 assert(method->method_holder()->is_tracing_known(), "klass must be known"); 108 109 added = false; 110 if (!method->is_tracing_known()) { 111 added = method->atomic_mark_tracing_known(); 112 } 113 return (TraceTypes::method_id) (intptr_t) method; 114 } 115 116 inline TraceTypes::stack_id TraceMetadata::next_stack_id() { 117 assert(EnableEventTracingStackTraces, "stack traces not enabled"); 118 return (TraceTypes::stack_id) Atomic::add_ptr(1, &_last_stack_id); 119 } 120 121 inline TraceTypes::seq_num TraceMetadata::next_global_seq() { 122 return (TraceTypes::seq_num) Atomic::add_ptr(1, &_last_global_seq); 123 } 124 125 inline const CachedTraceStack * TraceMetadata::get_or_try_add_stack(CompositeTraceStack &ts, bool &known, TraceTypes::stack_id preallocated_id) { 126 return _stack_cache->get_or_try_add(ts, known, preallocated_id); 127 } 128 129 inline void TraceMetadata::purge_unloading_classes(ClassLoaderData *loader) { 130 _stack_cache->purge_unloading_classes(loader); 131 } 132 133 inline void TraceMetadata::purge_unloading_nmethod(const nmethod *nm) { 134 _stack_cache->purge_unloading_nmethod(nm); 135 } 136 137 #endif /* SHARE_VM_EVTRACE_TRACEMETADATA_INLINE_HPP */